Mercurial > hg > truffle
comparison src/share/vm/oops/constantPoolOop.hpp @ 1913:3b2dea75431e
6984311: JSR 292 needs optional bootstrap method parameters
Summary: Allow CONSTANT_InvokeDynamic nodes to have any number of extra operands.
Reviewed-by: twisti
author | jrose |
---|---|
date | Sat, 30 Oct 2010 13:08:23 -0700 |
parents | d1896d1dda3e |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1912:8213b0f5c92d | 1913:3b2dea75431e |
---|---|
39 friend class BytecodeInterpreter; // Directly extracts an oop in the pool for fast instanceof/checkcast | 39 friend class BytecodeInterpreter; // Directly extracts an oop in the pool for fast instanceof/checkcast |
40 private: | 40 private: |
41 typeArrayOop _tags; // the tag array describing the constant pool's contents | 41 typeArrayOop _tags; // the tag array describing the constant pool's contents |
42 constantPoolCacheOop _cache; // the cache holding interpreter runtime information | 42 constantPoolCacheOop _cache; // the cache holding interpreter runtime information |
43 klassOop _pool_holder; // the corresponding class | 43 klassOop _pool_holder; // the corresponding class |
44 typeArrayOop _operands; // for variable-sized (InvokeDynamic) nodes, usually empty | |
44 int _flags; // a few header bits to describe contents for GC | 45 int _flags; // a few header bits to describe contents for GC |
45 int _length; // number of elements in the array | 46 int _length; // number of elements in the array |
46 volatile bool _is_conc_safe; // if true, safe for concurrent | 47 volatile bool _is_conc_safe; // if true, safe for concurrent |
47 // GC processing | 48 // GC processing |
48 // only set to non-zero if constant pool is merged by RedefineClasses | 49 // only set to non-zero if constant pool is merged by RedefineClasses |
50 | 51 |
51 void set_tags(typeArrayOop tags) { oop_store_without_check((oop*)&_tags, tags); } | 52 void set_tags(typeArrayOop tags) { oop_store_without_check((oop*)&_tags, tags); } |
52 void tag_at_put(int which, jbyte t) { tags()->byte_at_put(which, t); } | 53 void tag_at_put(int which, jbyte t) { tags()->byte_at_put(which, t); } |
53 void release_tag_at_put(int which, jbyte t) { tags()->release_byte_at_put(which, t); } | 54 void release_tag_at_put(int which, jbyte t) { tags()->release_byte_at_put(which, t); } |
54 | 55 |
56 void set_operands(typeArrayOop operands) { oop_store_without_check((oop*)&_operands, operands); } | |
57 | |
55 enum FlagBit { | 58 enum FlagBit { |
56 FB_has_invokedynamic = 1, | 59 FB_has_invokedynamic = 1, |
57 FB_has_pseudo_string = 2 | 60 FB_has_pseudo_string = 2 |
58 }; | 61 }; |
59 | 62 |
65 | 68 |
66 private: | 69 private: |
67 intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); } | 70 intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(constantPoolOopDesc)); } |
68 oop* tags_addr() { return (oop*)&_tags; } | 71 oop* tags_addr() { return (oop*)&_tags; } |
69 oop* cache_addr() { return (oop*)&_cache; } | 72 oop* cache_addr() { return (oop*)&_cache; } |
73 oop* operands_addr() { return (oop*)&_operands; } | |
70 | 74 |
71 oop* obj_at_addr(int which) const { | 75 oop* obj_at_addr(int which) const { |
72 assert(is_within_bounds(which), "index out of bounds"); | 76 assert(is_within_bounds(which), "index out of bounds"); |
73 return (oop*) &base()[which]; | 77 return (oop*) &base()[which]; |
74 } | 78 } |
93 return (jdouble*) &base()[which]; | 97 return (jdouble*) &base()[which]; |
94 } | 98 } |
95 | 99 |
96 public: | 100 public: |
97 typeArrayOop tags() const { return _tags; } | 101 typeArrayOop tags() const { return _tags; } |
102 typeArrayOop operands() const { return _operands; } | |
98 | 103 |
99 bool has_pseudo_string() const { return flag_at(FB_has_pseudo_string); } | 104 bool has_pseudo_string() const { return flag_at(FB_has_pseudo_string); } |
100 bool has_invokedynamic() const { return flag_at(FB_has_invokedynamic); } | 105 bool has_invokedynamic() const { return flag_at(FB_has_invokedynamic); } |
101 void set_pseudo_string() { set_flag_at(FB_has_pseudo_string); } | 106 void set_pseudo_string() { set_flag_at(FB_has_pseudo_string); } |
102 void set_invokedynamic() { set_flag_at(FB_has_invokedynamic); } | 107 void set_invokedynamic() { set_flag_at(FB_has_invokedynamic); } |
111 void set_cache(constantPoolCacheOop cache){ oop_store((oop*)&_cache, cache); } | 116 void set_cache(constantPoolCacheOop cache){ oop_store((oop*)&_cache, cache); } |
112 | 117 |
113 // Assembly code support | 118 // Assembly code support |
114 static int tags_offset_in_bytes() { return offset_of(constantPoolOopDesc, _tags); } | 119 static int tags_offset_in_bytes() { return offset_of(constantPoolOopDesc, _tags); } |
115 static int cache_offset_in_bytes() { return offset_of(constantPoolOopDesc, _cache); } | 120 static int cache_offset_in_bytes() { return offset_of(constantPoolOopDesc, _cache); } |
121 static int operands_offset_in_bytes() { return offset_of(constantPoolOopDesc, _operands); } | |
116 static int pool_holder_offset_in_bytes() { return offset_of(constantPoolOopDesc, _pool_holder); } | 122 static int pool_holder_offset_in_bytes() { return offset_of(constantPoolOopDesc, _pool_holder); } |
117 | 123 |
118 // Storing constants | 124 // Storing constants |
119 | 125 |
120 void klass_at_put(int which, klassOop k) { | 126 void klass_at_put(int which, klassOop k) { |
154 void method_type_index_at_put(int which, int ref_index) { | 160 void method_type_index_at_put(int which, int ref_index) { |
155 tag_at_put(which, JVM_CONSTANT_MethodType); | 161 tag_at_put(which, JVM_CONSTANT_MethodType); |
156 *int_at_addr(which) = ref_index; | 162 *int_at_addr(which) = ref_index; |
157 } | 163 } |
158 | 164 |
159 void invoke_dynamic_at_put(int which, int bootstrap_method_index, int name_and_type_index) { | 165 void invoke_dynamic_at_put(int which, int operand_base, int operand_count) { |
160 tag_at_put(which, JVM_CONSTANT_InvokeDynamic); | 166 tag_at_put(which, JVM_CONSTANT_InvokeDynamic); |
161 *int_at_addr(which) = ((jint) name_and_type_index<<16) | bootstrap_method_index; | 167 *int_at_addr(which) = operand_base; // this is the real information |
162 } | 168 } |
169 #ifdef ASSERT | |
170 bool check_invoke_dynamic_at(int which, | |
171 int bootstrap_method_index, | |
172 int name_and_type_index, | |
173 int argument_count) { | |
174 assert(invoke_dynamic_bootstrap_method_ref_index_at(which) == bootstrap_method_index, | |
175 "already stored by caller"); | |
176 assert(invoke_dynamic_name_and_type_ref_index_at(which) == name_and_type_index, | |
177 "already stored by caller"); | |
178 assert(invoke_dynamic_argument_count_at(which) == argument_count, | |
179 "consistent argument count"); | |
180 if (argument_count != 0) { | |
181 invoke_dynamic_argument_index_at(which, 0); | |
182 invoke_dynamic_argument_index_at(which, argument_count - 1); | |
183 } | |
184 return true; | |
185 } | |
186 #endif //ASSERT | |
163 | 187 |
164 // Temporary until actual use | 188 // Temporary until actual use |
165 void unresolved_string_at_put(int which, symbolOop s) { | 189 void unresolved_string_at_put(int which, symbolOop s) { |
166 *obj_at_addr(which) = NULL; | 190 *obj_at_addr(which) = NULL; |
167 release_tag_at_put(which, JVM_CONSTANT_UnresolvedString); | 191 release_tag_at_put(which, JVM_CONSTANT_UnresolvedString); |
399 } | 423 } |
400 symbolOop method_type_signature_at(int which) { | 424 symbolOop method_type_signature_at(int which) { |
401 int sym = method_type_index_at(which); | 425 int sym = method_type_index_at(which); |
402 return symbol_at(sym); | 426 return symbol_at(sym); |
403 } | 427 } |
428 | |
429 private: | |
430 // some nodes (InvokeDynamic) have a variable number of operands, each a u2 value | |
431 enum { _multi_operand_count_offset = -1, | |
432 _multi_operand_base_offset = 0, | |
433 _multi_operand_buffer_fill_pointer_offset = 0 // shared at front of operands array | |
434 }; | |
435 int multi_operand_buffer_length() { | |
436 return operands() == NULL ? 0 : operands()->length(); | |
437 } | |
438 int multi_operand_buffer_fill_pointer() { | |
439 return operands() == NULL | |
440 ? _multi_operand_buffer_fill_pointer_offset + 1 | |
441 : operands()->int_at(_multi_operand_buffer_fill_pointer_offset); | |
442 } | |
443 void multi_operand_buffer_grow(int min_length, TRAPS); | |
444 void set_multi_operand_buffer_fill_pointer(int fillp) { | |
445 assert(operands() != NULL, ""); | |
446 operands()->int_at_put(_multi_operand_buffer_fill_pointer_offset, fillp); | |
447 } | |
448 int multi_operand_base_at(int which) { | |
449 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); | |
450 int op_base = *int_at_addr(which); | |
451 assert(op_base > _multi_operand_buffer_fill_pointer_offset, "Corrupted operand base"); | |
452 return op_base; | |
453 } | |
454 int multi_operand_count_at(int which) { | |
455 int op_base = multi_operand_base_at(which); | |
456 assert((uint)(op_base + _multi_operand_count_offset) < (uint)operands()->length(), "oob"); | |
457 int count = operands()->int_at(op_base + _multi_operand_count_offset); | |
458 return count; | |
459 } | |
460 int multi_operand_ref_at(int which, int i) { | |
461 int op_base = multi_operand_base_at(which); | |
462 assert((uint)i < (uint)multi_operand_count_at(which), "oob"); | |
463 assert((uint)(op_base + _multi_operand_base_offset + i) < (uint)operands()->length(), "oob"); | |
464 return operands()->int_at(op_base + _multi_operand_base_offset + i); | |
465 } | |
466 void set_multi_operand_ref_at(int which, int i, int ref) { | |
467 DEBUG_ONLY(multi_operand_ref_at(which, i)); // trigger asserts | |
468 int op_base = multi_operand_base_at(which); | |
469 operands()->int_at_put(op_base + _multi_operand_base_offset + i, ref); | |
470 } | |
471 | |
472 public: | |
473 // layout of InvokeDynamic: | |
474 enum { | |
475 _indy_bsm_offset = 0, // CONSTANT_MethodHandle bsm | |
476 _indy_nt_offset = 1, // CONSTANT_NameAndType descr | |
477 _indy_argc_offset = 2, // u2 argc | |
478 _indy_argv_offset = 3 // u2 argv[argc] | |
479 }; | |
404 int invoke_dynamic_bootstrap_method_ref_index_at(int which) { | 480 int invoke_dynamic_bootstrap_method_ref_index_at(int which) { |
405 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); | 481 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); |
406 jint ref_index = *int_at_addr(which); | 482 return multi_operand_ref_at(which, _indy_bsm_offset); |
407 return extract_low_short_from_int(ref_index); | |
408 } | 483 } |
409 int invoke_dynamic_name_and_type_ref_index_at(int which) { | 484 int invoke_dynamic_name_and_type_ref_index_at(int which) { |
410 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); | 485 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); |
411 jint ref_index = *int_at_addr(which); | 486 return multi_operand_ref_at(which, _indy_nt_offset); |
412 return extract_high_short_from_int(ref_index); | 487 } |
488 int invoke_dynamic_argument_count_at(int which) { | |
489 assert(tag_at(which).is_invoke_dynamic(), "Corrupted constant pool"); | |
490 int argc = multi_operand_ref_at(which, _indy_argc_offset); | |
491 DEBUG_ONLY(int op_count = multi_operand_count_at(which)); | |
492 assert(_indy_argv_offset + argc == op_count, "consistent inner and outer counts"); | |
493 return argc; | |
494 } | |
495 int invoke_dynamic_argument_index_at(int which, int j) { | |
496 assert((uint)j < (uint)invoke_dynamic_argument_count_at(which), "oob"); | |
497 return multi_operand_ref_at(which, _indy_argv_offset + j); | |
413 } | 498 } |
414 | 499 |
415 // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve, | 500 // The following methods (name/signature/klass_ref_at, klass_ref_at_noresolve, |
416 // name_and_type_ref_index_at) all expect to be passed indices obtained | 501 // name_and_type_ref_index_at) all expect to be passed indices obtained |
417 // directly from the bytecode. | 502 // directly from the bytecode. |
446 void resolve_string_constants(TRAPS) { | 531 void resolve_string_constants(TRAPS) { |
447 constantPoolHandle h_this(THREAD, this); | 532 constantPoolHandle h_this(THREAD, this); |
448 resolve_string_constants_impl(h_this, CHECK); | 533 resolve_string_constants_impl(h_this, CHECK); |
449 } | 534 } |
450 | 535 |
536 private: | |
537 enum { _no_index_sentinel = -1, _possible_index_sentinel = -2 }; | |
538 public: | |
539 | |
451 // Resolve late bound constants. | 540 // Resolve late bound constants. |
452 oop resolve_constant_at(int index, TRAPS) { | 541 oop resolve_constant_at(int index, TRAPS) { |
453 constantPoolHandle h_this(THREAD, this); | 542 constantPoolHandle h_this(THREAD, this); |
454 return resolve_constant_at_impl(h_this, index, -1, THREAD); | 543 return resolve_constant_at_impl(h_this, index, _no_index_sentinel, THREAD); |
455 } | 544 } |
456 | 545 |
457 oop resolve_cached_constant_at(int cache_index, TRAPS) { | 546 oop resolve_cached_constant_at(int cache_index, TRAPS) { |
458 constantPoolHandle h_this(THREAD, this); | 547 constantPoolHandle h_this(THREAD, this); |
459 return resolve_constant_at_impl(h_this, -1, cache_index, THREAD); | 548 return resolve_constant_at_impl(h_this, _no_index_sentinel, cache_index, THREAD); |
549 } | |
550 | |
551 oop resolve_possibly_cached_constant_at(int pool_index, TRAPS) { | |
552 constantPoolHandle h_this(THREAD, this); | |
553 return resolve_constant_at_impl(h_this, pool_index, _possible_index_sentinel, THREAD); | |
460 } | 554 } |
461 | 555 |
462 // Klass name matches name at offset | 556 // Klass name matches name at offset |
463 bool klass_name_at_matches(instanceKlassHandle k, int which); | 557 bool klass_name_at_matches(instanceKlassHandle k, int which); |
464 | 558 |