sharkCacheDecache.hpp revision 1879:f95d63e2154a
1/*
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2008, 2009 Red Hat, Inc.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26#ifndef SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP
27#define SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP
28
29#include "ci/ciMethod.hpp"
30#include "code/debugInfoRec.hpp"
31#include "shark/sharkBuilder.hpp"
32#include "shark/sharkFunction.hpp"
33#include "shark/sharkStateScanner.hpp"
34
35// Class hierarchy:
36// - SharkStateScanner
37//   - SharkCacherDecacher
38//     - SharkDecacher
39//       - SharkJavaCallDecacher
40//       - SharkVMCallDecacher
41//       - SharkTrapDecacher
42//     - SharkCacher
43//       - SharkJavaCallCacher
44//       - SharkVMCallCacher
45//       - SharkFunctionEntryCacher
46//         - SharkNormalEntryCacher
47//         - SharkOSREntryCacher
48
49class SharkCacherDecacher : public SharkStateScanner {
50 protected:
51  SharkCacherDecacher(SharkFunction* function)
52    : SharkStateScanner(function) {}
53
54  // Helper
55 protected:
56  static int adjusted_offset(SharkValue* value, int offset) {
57    if (value->is_two_word())
58      offset--;
59    return offset;
60  }
61};
62
63class SharkDecacher : public SharkCacherDecacher {
64 protected:
65  SharkDecacher(SharkFunction* function, int bci)
66    : SharkCacherDecacher(function), _bci(bci) {}
67
68 private:
69  int _bci;
70
71 protected:
72  int bci() const {
73    return _bci;
74  }
75
76 private:
77  int                           _pc_offset;
78  OopMap*                       _oopmap;
79  GrowableArray<ScopeValue*>*   _exparray;
80  GrowableArray<MonitorValue*>* _monarray;
81  GrowableArray<ScopeValue*>*   _locarray;
82
83 private:
84  int pc_offset() const {
85    return _pc_offset;
86  }
87  OopMap* oopmap() const {
88    return _oopmap;
89  }
90  GrowableArray<ScopeValue*>* exparray() const {
91    return _exparray;
92  }
93  GrowableArray<MonitorValue*>* monarray() const {
94    return _monarray;
95  }
96  GrowableArray<ScopeValue*>* locarray() const {
97    return _locarray;
98  }
99
100  // Callbacks
101 protected:
102  void start_frame();
103
104  void start_stack(int stack_depth);
105  void process_stack_slot(int index, SharkValue** value, int offset);
106
107  void start_monitors(int num_monitors);
108  void process_monitor(int index, int box_offset, int obj_offset);
109
110  void process_oop_tmp_slot(llvm::Value** value, int offset);
111  void process_method_slot(llvm::Value** value, int offset);
112  void process_pc_slot(int offset);
113
114  void start_locals();
115  void process_local_slot(int index, SharkValue** value, int offset);
116
117  void end_frame();
118
119  // oopmap and debuginfo helpers
120 private:
121  static int oopmap_slot_munge(int offset) {
122    return SharkStack::oopmap_slot_munge(offset);
123  }
124  static VMReg slot2reg(int offset) {
125    return SharkStack::slot2reg(offset);
126  }
127  static Location slot2loc(int offset, Location::Type type) {
128    return Location::new_stk_loc(type, offset * wordSize);
129  }
130  static LocationValue* slot2lv(int offset, Location::Type type) {
131    return new LocationValue(slot2loc(offset, type));
132  }
133  static Location::Type location_type(SharkValue** addr, bool maybe_two_word) {
134    // low addresses this end
135    //                           Type       32-bit    64-bit
136    //   ----------------------------------------------------
137    //   stack[0]    local[3]    jobject    oop       oop
138    //   stack[1]    local[2]    NULL       normal    lng
139    //   stack[2]    local[1]    jlong      normal    invalid
140    //   stack[3]    local[0]    jint       normal    normal
141    //
142    // high addresses this end
143
144    SharkValue *value = *addr;
145    if (value) {
146      if (value->is_jobject())
147        return Location::oop;
148#ifdef _LP64
149      if (value->is_two_word())
150        return Location::invalid;
151#endif // _LP64
152      return Location::normal;
153    }
154    else {
155      if (maybe_two_word) {
156        value = *(addr - 1);
157        if (value && value->is_two_word()) {
158#ifdef _LP64
159          if (value->is_jlong())
160            return Location::lng;
161          if (value->is_jdouble())
162            return Location::dbl;
163          ShouldNotReachHere();
164#else
165          return Location::normal;
166#endif // _LP64
167        }
168      }
169      return Location::invalid;
170    }
171  }
172
173  // Stack slot helpers
174 protected:
175  virtual bool stack_slot_needs_write(int index, SharkValue* value) = 0;
176  virtual bool stack_slot_needs_oopmap(int index, SharkValue* value) = 0;
177  virtual bool stack_slot_needs_debuginfo(int index, SharkValue* value) = 0;
178
179  static Location::Type stack_location_type(int index, SharkValue** addr) {
180    return location_type(addr, *addr == NULL);
181  }
182
183  // Local slot helpers
184 protected:
185  virtual bool local_slot_needs_write(int index, SharkValue* value) = 0;
186  virtual bool local_slot_needs_oopmap(int index, SharkValue* value) = 0;
187  virtual bool local_slot_needs_debuginfo(int index, SharkValue* value) = 0;
188
189  static Location::Type local_location_type(int index, SharkValue** addr) {
190    return location_type(addr, index > 0);
191  }
192
193  // Writer helper
194 protected:
195  void write_value_to_frame(const llvm::Type* type,
196                            llvm::Value*      value,
197                            int               offset);
198};
199
200class SharkJavaCallDecacher : public SharkDecacher {
201 public:
202  SharkJavaCallDecacher(SharkFunction* function, int bci, ciMethod* callee)
203    : SharkDecacher(function, bci), _callee(callee) {}
204
205 private:
206  ciMethod* _callee;
207
208 protected:
209  ciMethod* callee() const {
210    return _callee;
211  }
212
213  // Stack slot helpers
214 protected:
215  bool stack_slot_needs_write(int index, SharkValue* value) {
216    return value && (index < callee()->arg_size() || value->is_jobject());
217  }
218  bool stack_slot_needs_oopmap(int index, SharkValue* value) {
219    return value && value->is_jobject() && index >= callee()->arg_size();
220  }
221  bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
222    return index >= callee()->arg_size();
223  }
224
225  // Local slot helpers
226 protected:
227  bool local_slot_needs_write(int index, SharkValue* value) {
228    return value && value->is_jobject();
229  }
230  bool local_slot_needs_oopmap(int index, SharkValue* value) {
231    return value && value->is_jobject();
232  }
233  bool local_slot_needs_debuginfo(int index, SharkValue* value) {
234    return true;
235  }
236};
237
238class SharkVMCallDecacher : public SharkDecacher {
239 public:
240  SharkVMCallDecacher(SharkFunction* function, int bci)
241    : SharkDecacher(function, bci) {}
242
243  // Stack slot helpers
244 protected:
245  bool stack_slot_needs_write(int index, SharkValue* value) {
246    return value && value->is_jobject();
247  }
248  bool stack_slot_needs_oopmap(int index, SharkValue* value) {
249    return value && value->is_jobject();
250  }
251  bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
252    return true;
253  }
254
255  // Local slot helpers
256 protected:
257  bool local_slot_needs_write(int index, SharkValue* value) {
258    return value && value->is_jobject();
259  }
260  bool local_slot_needs_oopmap(int index, SharkValue* value) {
261    return value && value->is_jobject();
262  }
263  bool local_slot_needs_debuginfo(int index, SharkValue* value) {
264    return true;
265  }
266};
267
268class SharkTrapDecacher : public SharkDecacher {
269 public:
270  SharkTrapDecacher(SharkFunction* function, int bci)
271    : SharkDecacher(function, bci) {}
272
273  // Stack slot helpers
274 protected:
275  bool stack_slot_needs_write(int index, SharkValue* value) {
276    return value != NULL;
277  }
278  bool stack_slot_needs_oopmap(int index, SharkValue* value) {
279    return value && value->is_jobject();
280  }
281  bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
282    return true;
283  }
284
285  // Local slot helpers
286 protected:
287  bool local_slot_needs_write(int index, SharkValue* value) {
288    return value != NULL;
289  }
290  bool local_slot_needs_oopmap(int index, SharkValue* value) {
291    return value && value->is_jobject();
292  }
293  bool local_slot_needs_debuginfo(int index, SharkValue* value) {
294    return true;
295  }
296};
297
298class SharkCacher : public SharkCacherDecacher {
299 protected:
300  SharkCacher(SharkFunction* function)
301    : SharkCacherDecacher(function) {}
302
303  // Callbacks
304 protected:
305  void process_stack_slot(int index, SharkValue** value, int offset);
306
307  void process_oop_tmp_slot(llvm::Value** value, int offset);
308  virtual void process_method_slot(llvm::Value** value, int offset);
309
310  virtual void process_local_slot(int index, SharkValue** value, int offset);
311
312  // Stack slot helper
313 protected:
314  virtual bool stack_slot_needs_read(int index, SharkValue* value) = 0;
315
316  // Local slot helper
317 protected:
318  virtual bool local_slot_needs_read(int index, SharkValue* value) {
319    return value && value->is_jobject();
320  }
321
322  // Writer helper
323 protected:
324  llvm::Value* read_value_from_frame(const llvm::Type* type, int offset);
325};
326
327class SharkJavaCallCacher : public SharkCacher {
328 public:
329  SharkJavaCallCacher(SharkFunction* function, ciMethod* callee)
330    : SharkCacher(function), _callee(callee) {}
331
332 private:
333  ciMethod* _callee;
334
335 protected:
336  ciMethod* callee() const {
337    return _callee;
338  }
339
340  // Stack slot helper
341 protected:
342  bool stack_slot_needs_read(int index, SharkValue* value) {
343    return value && (index < callee()->return_type()->size() ||
344                     value->is_jobject());
345  }
346};
347
348class SharkVMCallCacher : public SharkCacher {
349 public:
350  SharkVMCallCacher(SharkFunction* function)
351    : SharkCacher(function) {}
352
353  // Stack slot helper
354 protected:
355  bool stack_slot_needs_read(int index, SharkValue* value) {
356    return value && value->is_jobject();
357  }
358};
359
360class SharkFunctionEntryCacher : public SharkCacher {
361 public:
362  SharkFunctionEntryCacher(SharkFunction* function, llvm::Value* method)
363    : SharkCacher(function), _method(method) {}
364
365 private:
366  llvm::Value* _method;
367
368 private:
369  llvm::Value* method() const {
370    return _method;
371  }
372
373  // Method slot callback
374 protected:
375  void process_method_slot(llvm::Value** value, int offset);
376
377  // Stack slot helper
378 protected:
379  bool stack_slot_needs_read(int index, SharkValue* value) {
380    ShouldNotReachHere(); // entry block shouldn't have stack
381  }
382
383  // Local slot helper
384 protected:
385  bool local_slot_needs_read(int index, SharkValue* value) {
386    return value != NULL;
387  }
388};
389
390class SharkNormalEntryCacher : public SharkFunctionEntryCacher {
391 public:
392  SharkNormalEntryCacher(SharkFunction* function, llvm::Value* method)
393    : SharkFunctionEntryCacher(function, method) {}
394};
395
396class SharkOSREntryCacher : public SharkFunctionEntryCacher {
397 public:
398  SharkOSREntryCacher(SharkFunction* function,
399                      llvm::Value*   method,
400                      llvm::Value*   osr_buf)
401    : SharkFunctionEntryCacher(function, method),
402      _osr_buf(
403        builder()->CreateBitCast(
404          osr_buf,
405          llvm::PointerType::getUnqual(
406            llvm::ArrayType::get(
407              SharkType::intptr_type(),
408              max_locals() + max_monitors() * 2)))) {}
409
410 private:
411  llvm::Value* _osr_buf;
412
413 private:
414  llvm::Value* osr_buf() const {
415    return _osr_buf;
416  }
417
418  // Callbacks
419 protected:
420  void process_monitor(int index, int box_offset, int obj_offset);
421  void process_local_slot(int index, SharkValue** value, int offset);
422
423  // Helper
424 private:
425  llvm::Value* CreateAddressOfOSRBufEntry(int offset, const llvm::Type* type);
426};
427
428#endif // SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP
429