rev 47445 : 8171853: Remove Shark compiler
1 /*
2 * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_CODE_CODEBLOB_HPP
26 #define SHARE_VM_CODE_CODEBLOB_HPP
27
28 #include "asm/codeBuffer.hpp"
29 #include "compiler/compilerDefinitions.hpp"
30 #include "compiler/oopMap.hpp"
31 #include "runtime/frame.hpp"
32 #include "runtime/handles.hpp"
33 #include "utilities/align.hpp"
34 #include "utilities/macros.hpp"
35
36 // CodeBlob Types
37 // Used in the CodeCache to assign CodeBlobs to different CodeHeaps
38 struct CodeBlobType {
39 enum {
40 MethodNonProfiled = 0, // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods)
41 MethodProfiled = 1, // Execution level 2 and 3 (profiled) nmethods
42 NonNMethod = 2, // Non-nmethods like Buffers, Adapters and Runtime Stubs
43 All = 3, // All types (No code cache segmentation)
44 AOT = 4, // AOT methods
45 NumTypes = 5 // Number of CodeBlobTypes
46 };
47 };
48
49 // CodeBlob - superclass for all entries in the CodeCache.
50 //
51 // Subtypes are:
52 // CompiledMethod : Compiled Java methods (include method that calls to native code)
53 // nmethod : JIT Compiled Java methods
54 // RuntimeBlob : Non-compiled method code; generated glue code
55 // RuntimeStub : Call to VM runtime methods
56 // DeoptimizationBlob : Used for deoptimization
57 // ExceptionBlob : Used for stack unrolling
58 // SafepointBlob : Used to handle illegal instruction exceptions
59 //
60 //
61 // Layout:
62 // - header
63 // - relocation
64 // - content space
65 // - instruction space
66 // - data space
67
68
69 class CodeBlobLayout;
70
71 class CodeBlob VALUE_OBJ_CLASS_SPEC {
72 friend class VMStructs;
73 friend class JVMCIVMStructs;
74 friend class CodeCacheDumper;
75
76 protected:
77
78 const CompilerType _type; // CompilerType
79 int _size; // total size of CodeBlob in bytes
80 int _header_size; // size of header (depends on subclass)
81 int _frame_complete_offset; // instruction offsets in [0.._frame_complete_offset) have
82 // not finished setting up their frame. Beware of pc's in
83 // that range. There is a similar range(s) on returns
84 // which we don't detect.
85 int _data_offset; // offset to where data region begins
86 int _frame_size; // size of stack frame
87
88 address _code_begin;
89 address _code_end;
90 address _content_begin; // address to where content region begins (this includes consts, insts, stubs)
91 // address _content_end - not required, for all CodeBlobs _code_end == _content_end for now
92 address _data_end;
93 address _relocation_begin;
94 address _relocation_end;
95
96 ImmutableOopMapSet* _oop_maps; // OopMap for this CodeBlob
97 bool _caller_must_gc_arguments;
98 CodeStrings _strings;
99 const char* _name;
100 S390_ONLY(int _ctable_offset;)
101
102 CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
103 CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
104 public:
105 // Returns the space needed for CodeBlob
106 static unsigned int allocation_size(CodeBuffer* cb, int header_size);
107 static unsigned int align_code_offset(int offset);
108
109 // Deletion
110 virtual void flush();
111
112 // Typing
113 virtual bool is_buffer_blob() const { return false; }
114 virtual bool is_nmethod() const { return false; }
115 virtual bool is_runtime_stub() const { return false; }
116 virtual bool is_deoptimization_stub() const { return false; }
117 virtual bool is_uncommon_trap_stub() const { return false; }
118 virtual bool is_exception_stub() const { return false; }
119 virtual bool is_safepoint_stub() const { return false; }
120 virtual bool is_adapter_blob() const { return false; }
121 virtual bool is_method_handles_adapter_blob() const { return false; }
122 virtual bool is_aot() const { return false; }
123 virtual bool is_compiled() const { return false; }
124
125 inline bool is_compiled_by_c1() const { return _type == compiler_c1; };
126 inline bool is_compiled_by_c2() const { return _type == compiler_c2; };
127 inline bool is_compiled_by_jvmci() const { return _type == compiler_jvmci; };
128 inline bool is_compiled_by_shark() const { return _type == compiler_shark; };
129 const char* compiler_name() const;
130
131 // Casting
132 nmethod* as_nmethod_or_null() { return is_nmethod() ? (nmethod*) this : NULL; }
133 nmethod* as_nmethod() { assert(is_nmethod(), "must be nmethod"); return (nmethod*) this; }
134 CompiledMethod* as_compiled_method_or_null() { return is_compiled() ? (CompiledMethod*) this : NULL; }
135 CompiledMethod* as_compiled_method() { assert(is_compiled(), "must be compiled"); return (CompiledMethod*) this; }
136 CodeBlob* as_codeblob_or_null() const { return (CodeBlob*) this; }
137
138 // Boundaries
139 address header_begin() const { return (address) this; }
140 relocInfo* relocation_begin() const { return (relocInfo*) _relocation_begin; };
141 relocInfo* relocation_end() const { return (relocInfo*) _relocation_end; }
142 address content_begin() const { return _content_begin; }
143 address content_end() const { return _code_end; } // _code_end == _content_end is true for all types of blobs for now, it is also checked in the constructor
144 address code_begin() const { return _code_begin; }
145 address code_end() const { return _code_end; }
146 address data_end() const { return _data_end; }
147
148 // This field holds the beginning of the const section in the old code buffer.
149 // It is needed to fix relocations of pc-relative loads when resizing the
150 // the constant pool or moving it.
151 S390_ONLY(address ctable_begin() const { return header_begin() + _ctable_offset; })
152 void set_ctable_begin(address ctable) { S390_ONLY(_ctable_offset = ctable - header_begin();) }
153
154 // Sizes
155 int size() const { return _size; }
156 int header_size() const { return _header_size; }
157 int relocation_size() const { return (address) relocation_end() - (address) relocation_begin(); }
158 int content_size() const { return content_end() - content_begin(); }
159 int code_size() const { return code_end() - code_begin(); }
160
161 // Containment
162 bool blob_contains(address addr) const { return header_begin() <= addr && addr < data_end(); }
163 bool code_contains(address addr) const { return code_begin() <= addr && addr < code_end(); }
164 bool contains(address addr) const { return content_begin() <= addr && addr < content_end(); }
165 bool is_frame_complete_at(address addr) const { return _frame_complete_offset != CodeOffsets::frame_never_safe &&
166 code_contains(addr) && addr >= code_begin() + _frame_complete_offset; }
167
168 // CodeCache support: really only used by the nmethods, but in order to get
169 // asserts and certain bookkeeping to work in the CodeCache they are defined
170 // virtual here.
171 virtual bool is_zombie() const { return false; }
172 virtual bool is_locked_by_vm() const { return false; }
173
174 virtual bool is_unloaded() const { return false; }
175 virtual bool is_not_entrant() const { return false; }
176
177 // GC support
178 virtual bool is_alive() const = 0;
179
180 // OopMap for frame
181 ImmutableOopMapSet* oop_maps() const { return _oop_maps; }
182 void set_oop_maps(OopMapSet* p);
183 const ImmutableOopMap* oop_map_for_return_address(address return_address);
184 virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) = 0;
185
186 // Frame support
187 int frame_size() const { return _frame_size; }
188 void set_frame_size(int size) { _frame_size = size; }
189
190 // Returns true, if the next frame is responsible for GC'ing oops passed as arguments
191 bool caller_must_gc_arguments(JavaThread* thread) const { return _caller_must_gc_arguments; }
192
193 // Naming
194 const char* name() const { return _name; }
195 void set_name(const char* name) { _name = name; }
196
197 // Debugging
198 virtual void verify() = 0;
199 virtual void print() const { print_on(tty); };
200 virtual void print_on(outputStream* st) const;
201 virtual void print_value_on(outputStream* st) const;
202 void print_code();
203
204 // Print the comment associated with offset on stream, if there is one
205 virtual void print_block_comment(outputStream* stream, address block_begin) const {
206 intptr_t offset = (intptr_t)(block_begin - code_begin());
207 _strings.print_block_comment(stream, offset);
208 }
209
210 // Transfer ownership of comments to this CodeBlob
211 void set_strings(CodeStrings& strings) {
212 assert(!is_aot(), "invalid on aot");
213 _strings.assign(strings);
214 }
215
216 static ByteSize name_field_offset() {
217 return byte_offset_of(CodeBlob, _name);
218 }
219
220 static ByteSize oop_maps_field_offset() {
221 return byte_offset_of(CodeBlob, _oop_maps);
222 }
223 };
224
225 class CodeBlobLayout : public StackObj {
226 private:
227 int _size;
228 int _header_size;
229 int _relocation_size;
230 int _content_offset;
231 int _code_offset;
232 int _data_offset;
233 address _code_begin;
234 address _code_end;
235 address _content_begin;
236 address _content_end;
237 address _data_end;
238 address _relocation_begin;
239 address _relocation_end;
240
241 public:
242 CodeBlobLayout(address code_begin, address code_end, address content_begin, address content_end, address data_end, address relocation_begin, address relocation_end) :
243 _size(0),
244 _header_size(0),
245 _relocation_size(0),
246 _content_offset(0),
247 _code_offset(0),
248 _data_offset(0),
249 _content_begin(content_begin),
250 _content_end(content_end),
251 _code_begin(code_begin),
252 _code_end(code_end),
253 _data_end(data_end),
254 _relocation_begin(relocation_begin),
255 _relocation_end(relocation_end)
256 {
257 }
258
259 CodeBlobLayout(const address start, int size, int header_size, int relocation_size, int data_offset) :
260 _size(size),
261 _header_size(header_size),
262 _relocation_size(relocation_size),
263 _content_offset(CodeBlob::align_code_offset(_header_size + _relocation_size)),
264 _code_offset(_content_offset),
265 _data_offset(data_offset)
266 {
267 assert(is_aligned(_relocation_size, oopSize), "unaligned size");
268
269 _code_begin = (address) start + _code_offset;
270 _code_end = (address) start + _data_offset;
271
272 _content_begin = (address) start + _content_offset;
273 _content_end = (address) start + _data_offset;
274
275 _data_end = (address) start + _size;
276 _relocation_begin = (address) start + _header_size;
277 _relocation_end = _relocation_begin + _relocation_size;
278 }
279
280 CodeBlobLayout(const address start, int size, int header_size, const CodeBuffer* cb) :
281 _size(size),
282 _header_size(header_size),
283 _relocation_size(align_up(cb->total_relocation_size(), oopSize)),
284 _content_offset(CodeBlob::align_code_offset(_header_size + _relocation_size)),
285 _code_offset(_content_offset + cb->total_offset_of(cb->insts())),
286 _data_offset(_content_offset + align_up(cb->total_content_size(), oopSize))
287 {
288 assert(is_aligned(_relocation_size, oopSize), "unaligned size");
289
290 _code_begin = (address) start + _code_offset;
291 _code_end = (address) start + _data_offset;
292
293 _content_begin = (address) start + _content_offset;
294 _content_end = (address) start + _data_offset;
295
296 _data_end = (address) start + _size;
297 _relocation_begin = (address) start + _header_size;
298 _relocation_end = _relocation_begin + _relocation_size;
299 }
300
301 int size() const { return _size; }
302 int header_size() const { return _header_size; }
303 int relocation_size() const { return _relocation_size; }
304 int content_offset() const { return _content_offset; }
305 int code_offset() const { return _code_offset; }
306 int data_offset() const { return _data_offset; }
307 address code_begin() const { return _code_begin; }
308 address code_end() const { return _code_end; }
309 address data_end() const { return _data_end; }
310 address relocation_begin() const { return _relocation_begin; }
311 address relocation_end() const { return _relocation_end; }
312 address content_begin() const { return _content_begin; }
313 address content_end() const { return _content_end; }
314 };
315
316
317 class RuntimeBlob : public CodeBlob {
318 friend class VMStructs;
319 public:
320
321 // Creation
322 // a) simple CodeBlob
323 // frame_complete is the offset from the beginning of the instructions
324 // to where the frame setup (from stackwalk viewpoint) is complete.
325 RuntimeBlob(const char* name, int header_size, int size, int frame_complete, int locs_size);
326
327 // b) full CodeBlob
328 RuntimeBlob(
329 const char* name,
330 CodeBuffer* cb,
331 int header_size,
332 int size,
333 int frame_complete,
334 int frame_size,
335 OopMapSet* oop_maps,
336 bool caller_must_gc_arguments = false
337 );
338
339 // GC support
340 virtual bool is_alive() const = 0;
341
342 void verify();
343
344 // OopMap for frame
345 virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { ShouldNotReachHere(); }
346
347 // Debugging
348 void print() const { print_on(tty); }
349 virtual void print_on(outputStream* st) const { CodeBlob::print_on(st); }
350 virtual void print_value_on(outputStream* st) const { CodeBlob::print_value_on(st); }
351
352 // Deal with Disassembler, VTune, Forte, JvmtiExport, MemoryService.
353 static void trace_new_stub(RuntimeBlob* blob, const char* name1, const char* name2 = "");
354 };
355
356 class WhiteBox;
357 //----------------------------------------------------------------------------------------------------
358 // BufferBlob: used to hold non-relocatable machine code such as the interpreter, stubroutines, etc.
359
360 class BufferBlob: public RuntimeBlob {
361 friend class VMStructs;
362 friend class AdapterBlob;
363 friend class MethodHandlesAdapterBlob;
364 friend class WhiteBox;
365
366 private:
367 // Creation support
368 BufferBlob(const char* name, int size);
369 BufferBlob(const char* name, int size, CodeBuffer* cb);
370
371 void* operator new(size_t s, unsigned size) throw();
372
373 public:
374 // Creation
375 static BufferBlob* create(const char* name, int buffer_size);
376 static BufferBlob* create(const char* name, CodeBuffer* cb);
377
378 static void free(BufferBlob* buf);
379
380 // Typing
381 virtual bool is_buffer_blob() const { return true; }
382
383 // GC/Verification support
384 void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }
385 bool is_alive() const { return true; }
386
387 void verify();
388 void print_on(outputStream* st) const;
389 void print_value_on(outputStream* st) const;
390 };
391
392
393 //----------------------------------------------------------------------------------------------------
394 // AdapterBlob: used to hold C2I/I2C adapters
395
396 class AdapterBlob: public BufferBlob {
397 private:
398 AdapterBlob(int size, CodeBuffer* cb);
399
400 public:
401 // Creation
402 static AdapterBlob* create(CodeBuffer* cb);
403
404 // Typing
405 virtual bool is_adapter_blob() const { return true; }
406 };
407
408
409 //----------------------------------------------------------------------------------------------------
410 // MethodHandlesAdapterBlob: used to hold MethodHandles adapters
411
412 class MethodHandlesAdapterBlob: public BufferBlob {
413 private:
414 MethodHandlesAdapterBlob(int size) : BufferBlob("MethodHandles adapters", size) {}
415
416 public:
417 // Creation
418 static MethodHandlesAdapterBlob* create(int buffer_size);
419
420 // Typing
421 virtual bool is_method_handles_adapter_blob() const { return true; }
422 };
423
424
425 //----------------------------------------------------------------------------------------------------
426 // RuntimeStub: describes stubs used by compiled code to call a (static) C++ runtime routine
427
428 class RuntimeStub: public RuntimeBlob {
429 friend class VMStructs;
430 private:
431 // Creation support
432 RuntimeStub(
433 const char* name,
434 CodeBuffer* cb,
435 int size,
436 int frame_complete,
437 int frame_size,
438 OopMapSet* oop_maps,
439 bool caller_must_gc_arguments
440 );
441
442 void* operator new(size_t s, unsigned size) throw();
443
444 public:
445 // Creation
446 static RuntimeStub* new_runtime_stub(
447 const char* stub_name,
448 CodeBuffer* cb,
449 int frame_complete,
450 int frame_size,
451 OopMapSet* oop_maps,
452 bool caller_must_gc_arguments
453 );
454
455 // Typing
456 bool is_runtime_stub() const { return true; }
457
458 address entry_point() const { return code_begin(); }
459
460 // GC/Verification support
461 void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }
462 bool is_alive() const { return true; }
463
464 void verify();
465 void print_on(outputStream* st) const;
466 void print_value_on(outputStream* st) const;
467 };
468
469
470 //----------------------------------------------------------------------------------------------------
471 // Super-class for all blobs that exist in only one instance. Implements default behaviour.
472
473 class SingletonBlob: public RuntimeBlob {
474 friend class VMStructs;
475
476 protected:
477 void* operator new(size_t s, unsigned size) throw();
478
479 public:
480 SingletonBlob(
481 const char* name,
482 CodeBuffer* cb,
483 int header_size,
484 int size,
485 int frame_size,
486 OopMapSet* oop_maps
487 )
488 : RuntimeBlob(name, cb, header_size, size, CodeOffsets::frame_never_safe, frame_size, oop_maps)
489 {};
490
491 address entry_point() { return code_begin(); }
492
493 bool is_alive() const { return true; }
494
495 // GC/Verification support
496 void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }
497 void verify(); // does nothing
498 void print_on(outputStream* st) const;
499 void print_value_on(outputStream* st) const;
500 };
501
502
503 //----------------------------------------------------------------------------------------------------
504 // DeoptimizationBlob
505
506 class DeoptimizationBlob: public SingletonBlob {
507 friend class VMStructs;
508 friend class JVMCIVMStructs;
509 private:
510 int _unpack_offset;
511 int _unpack_with_exception;
512 int _unpack_with_reexecution;
513
514 int _unpack_with_exception_in_tls;
515
516 #if INCLUDE_JVMCI
517 // Offsets when JVMCI calls uncommon_trap.
518 int _uncommon_trap_offset;
519 int _implicit_exception_uncommon_trap_offset;
520 #endif
521
522 // Creation support
523 DeoptimizationBlob(
524 CodeBuffer* cb,
525 int size,
526 OopMapSet* oop_maps,
527 int unpack_offset,
528 int unpack_with_exception_offset,
529 int unpack_with_reexecution_offset,
530 int frame_size
531 );
532
533 public:
534 // Creation
535 static DeoptimizationBlob* create(
536 CodeBuffer* cb,
537 OopMapSet* oop_maps,
538 int unpack_offset,
539 int unpack_with_exception_offset,
540 int unpack_with_reexecution_offset,
541 int frame_size
542 );
543
544 // Typing
545 bool is_deoptimization_stub() const { return true; }
546 bool exception_address_is_unpack_entry(address pc) const {
547 address unpack_pc = unpack();
548 return (pc == unpack_pc || (pc + frame::pc_return_offset) == unpack_pc);
549 }
550
551 // GC for args
552 void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* Nothing to do */ }
553
554 // Printing
555 void print_value_on(outputStream* st) const;
556
557 address unpack() const { return code_begin() + _unpack_offset; }
558 address unpack_with_exception() const { return code_begin() + _unpack_with_exception; }
559 address unpack_with_reexecution() const { return code_begin() + _unpack_with_reexecution; }
560
561 // Alternate entry point for C1 where the exception and issuing pc
562 // are in JavaThread::_exception_oop and JavaThread::_exception_pc
563 // instead of being in registers. This is needed because C1 doesn't
564 // model exception paths in a way that keeps these registers free so
565 // there may be live values in those registers during deopt.
566 void set_unpack_with_exception_in_tls_offset(int offset) {
567 _unpack_with_exception_in_tls = offset;
568 assert(code_contains(code_begin() + _unpack_with_exception_in_tls), "must be PC inside codeblob");
569 }
570 address unpack_with_exception_in_tls() const { return code_begin() + _unpack_with_exception_in_tls; }
571
572 #if INCLUDE_JVMCI
573 // Offsets when JVMCI calls uncommon_trap.
574 void set_uncommon_trap_offset(int offset) {
575 _uncommon_trap_offset = offset;
576 assert(contains(code_begin() + _uncommon_trap_offset), "must be PC inside codeblob");
577 }
578 address uncommon_trap() const { return code_begin() + _uncommon_trap_offset; }
579
580 void set_implicit_exception_uncommon_trap_offset(int offset) {
581 _implicit_exception_uncommon_trap_offset = offset;
582 assert(contains(code_begin() + _implicit_exception_uncommon_trap_offset), "must be PC inside codeblob");
583 }
584 address implicit_exception_uncommon_trap() const { return code_begin() + _implicit_exception_uncommon_trap_offset; }
585 #endif // INCLUDE_JVMCI
586 };
587
588
589 //----------------------------------------------------------------------------------------------------
590 // UncommonTrapBlob (currently only used by Compiler 2)
591
592 #ifdef COMPILER2
593
594 class UncommonTrapBlob: public SingletonBlob {
595 friend class VMStructs;
596 private:
597 // Creation support
598 UncommonTrapBlob(
599 CodeBuffer* cb,
600 int size,
601 OopMapSet* oop_maps,
602 int frame_size
603 );
604
605 public:
606 // Creation
607 static UncommonTrapBlob* create(
608 CodeBuffer* cb,
609 OopMapSet* oop_maps,
610 int frame_size
611 );
612
613 // GC for args
614 void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* nothing to do */ }
615
616 // Typing
617 bool is_uncommon_trap_stub() const { return true; }
618 };
619
620
621 //----------------------------------------------------------------------------------------------------
622 // ExceptionBlob: used for exception unwinding in compiled code (currently only used by Compiler 2)
623
624 class ExceptionBlob: public SingletonBlob {
625 friend class VMStructs;
626 private:
627 // Creation support
628 ExceptionBlob(
629 CodeBuffer* cb,
630 int size,
631 OopMapSet* oop_maps,
632 int frame_size
633 );
634
635 public:
636 // Creation
637 static ExceptionBlob* create(
638 CodeBuffer* cb,
639 OopMapSet* oop_maps,
640 int frame_size
641 );
642
643 // GC for args
644 void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }
645
646 // Typing
647 bool is_exception_stub() const { return true; }
648 };
649 #endif // COMPILER2
650
651
652 //----------------------------------------------------------------------------------------------------
653 // SafepointBlob: handles illegal_instruction exceptions during a safepoint
654
655 class SafepointBlob: public SingletonBlob {
656 friend class VMStructs;
657 private:
658 // Creation support
659 SafepointBlob(
660 CodeBuffer* cb,
661 int size,
662 OopMapSet* oop_maps,
663 int frame_size
664 );
665
666 public:
667 // Creation
668 static SafepointBlob* create(
669 CodeBuffer* cb,
670 OopMapSet* oop_maps,
671 int frame_size
672 );
673
674 // GC for args
675 void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) { /* nothing to do */ }
676
677 // Typing
678 bool is_safepoint_stub() const { return true; }
679 };
680
681 #endif // SHARE_VM_CODE_CODEBLOB_HPP
--- EOF ---