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