Mercurial > hg > truffle
comparison src/share/vm/graal/graalCodeInstaller.cpp @ 6996:eec373d34caf
added support for annotated Constants and used it to track Klass* values in Graal and register them in the metadata section of a nmethod during code installation
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 20 Nov 2012 22:49:27 +0100 |
parents | 41938af2b3d8 |
children | bf2ea3ed3bce |
comparison
equal
deleted
inserted
replaced
6995:edb2d7ed9a01 | 6996:eec373d34caf |
---|---|
100 } | 100 } |
101 | 101 |
102 return map; | 102 return map; |
103 } | 103 } |
104 | 104 |
105 static ScopeValue* get_hotspot_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second) { | 105 // Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedJavaType.klass()). |
106 static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) { | |
107 char kind = Kind::typeChar(Constant::kind(constant)); | |
108 char wordKind = 'j'; | |
109 if (kind == wordKind) { | |
110 oop obj = Constant::object(constant); | |
111 jlong prim = Constant::primitive(constant); | |
112 if (obj != NULL) { | |
113 if (obj->is_a(HotSpotResolvedJavaType::klass())) { | |
114 Klass* klass = (Klass*) (address) HotSpotResolvedJavaType::metaspaceKlass(obj); | |
115 assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim)); | |
116 int index = oop_recorder->find_index(klass); | |
117 TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string()); | |
118 } else { | |
119 assert(java_lang_String::is_instance(obj), | |
120 err_msg("unexpected annotation type (%s) for constant %ld (%p) of kind %c", obj->klass()->name()->as_C_string(), prim, prim, kind)); | |
121 } | |
122 } | |
123 } | |
124 } | |
125 | |
126 static ScopeValue* get_hotspot_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder) { | |
106 second = NULL; | 127 second = NULL; |
107 if (value == Value::ILLEGAL()) { | 128 if (value == Value::ILLEGAL()) { |
108 return new LocationValue(Location::new_stk_loc(Location::invalid, 0)); | 129 return new LocationValue(Location::new_stk_loc(Location::invalid, 0)); |
109 } | 130 } |
110 | 131 |
155 if (type == T_DOUBLE || type == T_LONG) { | 176 if (type == T_DOUBLE || type == T_LONG) { |
156 second = value; | 177 second = value; |
157 } | 178 } |
158 return value; | 179 return value; |
159 } else if (value->is_a(Constant::klass())){ | 180 } else if (value->is_a(Constant::klass())){ |
160 oop obj = Constant::object(value); | 181 record_metadata_in_constant(value, oop_recorder); |
161 jlong prim = Constant::primitive(value); | 182 jlong prim = Constant::primitive(value); |
162 if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) { | 183 if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) { |
163 return new ConstantIntValue(*(jint*)&prim); | 184 return new ConstantIntValue(*(jint*)&prim); |
164 } else if (type == T_LONG || type == T_DOUBLE) { | 185 } else if (type == T_LONG || type == T_DOUBLE) { |
165 second = new ConstantIntValue(0); | 186 second = new ConstantIntValue(0); |
193 objects->append(sv); | 214 objects->append(sv); |
194 | 215 |
195 arrayOop values = (arrayOop) VirtualObject::values(value); | 216 arrayOop values = (arrayOop) VirtualObject::values(value); |
196 for (jint i = 0; i < values->length(); i++) { | 217 for (jint i = 0; i < values->length(); i++) { |
197 ScopeValue* cur_second = NULL; | 218 ScopeValue* cur_second = NULL; |
198 ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], total_frame_size, objects, cur_second); | 219 ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], total_frame_size, objects, cur_second, oop_recorder); |
199 | 220 |
200 if (isLongArray && cur_second == NULL) { | 221 if (isLongArray && cur_second == NULL) { |
201 // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations. | 222 // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations. |
202 // add an int 0 constant | 223 // add an int 0 constant |
203 #ifdef VM_LITTLE_ENDIAN | 224 #ifdef VM_LITTLE_ENDIAN |
220 } | 241 } |
221 ShouldNotReachHere(); | 242 ShouldNotReachHere(); |
222 return NULL; | 243 return NULL; |
223 } | 244 } |
224 | 245 |
225 static MonitorValue* get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects) { | 246 static MonitorValue* get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, OopRecorder* oop_recorder) { |
226 guarantee(value->is_a(code_MonitorValue::klass()), "Monitors must be of type MonitorValue"); | 247 guarantee(value->is_a(code_MonitorValue::klass()), "Monitors must be of type MonitorValue"); |
227 | 248 |
228 ScopeValue* second = NULL; | 249 ScopeValue* second = NULL; |
229 ScopeValue* owner_value = get_hotspot_value(code_MonitorValue::owner(value), total_frame_size, objects, second); | 250 ScopeValue* owner_value = get_hotspot_value(code_MonitorValue::owner(value), total_frame_size, objects, second, oop_recorder); |
230 assert(second == NULL, "monitor cannot occupy two stack slots"); | 251 assert(second == NULL, "monitor cannot occupy two stack slots"); |
231 | 252 |
232 ScopeValue* lock_data_value = get_hotspot_value(code_MonitorValue::lockData(value), total_frame_size, objects, second); | 253 ScopeValue* lock_data_value = get_hotspot_value(code_MonitorValue::lockData(value), total_frame_size, objects, second, oop_recorder); |
233 assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots"); | 254 assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots"); |
234 assert(lock_data_value->is_location(), "invalid monitor location"); | 255 assert(lock_data_value->is_location(), "invalid monitor location"); |
235 Location lock_data_loc = ((LocationValue*)lock_data_value)->location(); | 256 Location lock_data_loc = ((LocationValue*)lock_data_value)->location(); |
236 | 257 |
237 bool eliminated = false; | 258 bool eliminated = false; |
480 for (jint i = 0; i < values->length(); i++) { | 501 for (jint i = 0; i < values->length(); i++) { |
481 ScopeValue* second = NULL; | 502 ScopeValue* second = NULL; |
482 oop value = ((oop*) values->base(T_OBJECT))[i]; | 503 oop value = ((oop*) values->base(T_OBJECT))[i]; |
483 | 504 |
484 if (i < local_count) { | 505 if (i < local_count) { |
485 ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second); | 506 ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second, _oop_recorder); |
486 if (second != NULL) { | 507 if (second != NULL) { |
487 locals->append(second); | 508 locals->append(second); |
488 } | 509 } |
489 locals->append(first); | 510 locals->append(first); |
490 } else if (i < local_count + expression_count) { | 511 } else if (i < local_count + expression_count) { |
491 ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second); | 512 ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second, _oop_recorder); |
492 if (second != NULL) { | 513 if (second != NULL) { |
493 expressions->append(second); | 514 expressions->append(second); |
494 } | 515 } |
495 expressions->append(first); | 516 expressions->append(first); |
496 } else { | 517 } else { |
497 monitors->append(get_monitor_value(value, _total_frame_size, objects)); | 518 monitors->append(get_monitor_value(value, _total_frame_size, objects, _oop_recorder)); |
498 } | 519 } |
499 if (second != NULL) { | 520 if (second != NULL) { |
500 i++; | 521 i++; |
501 assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL"); | 522 assert(i < values->length(), "double-slot value not followed by Value.ILLEGAL"); |
502 assert(((oop*) values->base(T_OBJECT))[i] == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL"); | 523 assert(((oop*) values->base(T_OBJECT))[i] == Value::ILLEGAL(), "double-slot value not followed by Value.ILLEGAL"); |
599 } else { | 620 } else { |
600 NativeJump* jump = nativeJump_at((address) (inst)); | 621 NativeJump* jump = nativeJump_at((address) (inst)); |
601 jump->set_jump_destination(VmIds::getStub(global_stub)); | 622 jump->set_jump_destination(VmIds::getStub(global_stub)); |
602 _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); | 623 _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand); |
603 } | 624 } |
604 TRACE_graal_3("relocating (stub) at %016x", inst); | 625 TRACE_graal_3("relocating (stub) at %p", inst); |
605 } else { // method != NULL | 626 } else { // method != NULL |
606 assert(hotspot_method != NULL, "unexpected JavaMethod"); | 627 assert(hotspot_method != NULL, "unexpected JavaMethod"); |
607 assert(debug_info != NULL, "debug info expected"); | 628 assert(debug_info != NULL, "debug info expected"); |
608 | 629 |
609 Method* method = NULL; | 630 Method* method = NULL; |
657 } | 678 } |
658 | 679 |
659 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { | 680 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { |
660 oop constant = CompilationResult_DataPatch::constant(site); | 681 oop constant = CompilationResult_DataPatch::constant(site); |
661 int alignment = CompilationResult_DataPatch::alignment(site); | 682 int alignment = CompilationResult_DataPatch::alignment(site); |
683 bool inlined = CompilationResult_DataPatch::inlined(site); | |
662 oop kind = Constant::kind(constant); | 684 oop kind = Constant::kind(constant); |
663 | 685 |
664 address instruction = _instructions->start() + pc_offset; | 686 address instruction = _instructions->start() + pc_offset; |
665 | 687 |
666 char typeChar = Kind::typeChar(kind); | 688 char typeChar = Kind::typeChar(kind); |
673 fatal("int-sized values not expected in DataPatch"); | 695 fatal("int-sized values not expected in DataPatch"); |
674 break; | 696 break; |
675 case 'f': | 697 case 'f': |
676 case 'j': | 698 case 'j': |
677 case 'd': { | 699 case 'd': { |
678 address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); | 700 record_metadata_in_constant(constant, _oop_recorder); |
679 address next_instruction = Assembler::locate_next_instruction(instruction); | 701 if (inlined) { |
680 int size = _constants->size(); | 702 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); |
681 if (alignment > 0) { | 703 *((jlong*) operand) = Constant::primitive(constant); |
682 guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); | 704 } else { |
683 size = align_size_up(size, alignment); | 705 address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); |
684 } | 706 address next_instruction = Assembler::locate_next_instruction(instruction); |
685 // we don't care if this is a long/double/etc., the primitive field contains the right bits | 707 int size = _constants->size(); |
686 address dest = _constants->start() + size; | 708 if (alignment > 0) { |
687 _constants->set_end(dest + BytesPerLong); | 709 guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); |
688 *(jlong*) dest = Constant::primitive(constant); | 710 size = align_size_up(size, alignment); |
689 | 711 } |
690 long disp = dest - next_instruction; | 712 // we don't care if this is a long/double/etc., the primitive field contains the right bits |
691 assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); | 713 address dest = _constants->start() + size; |
692 *((jint*) operand) = (jint) disp; | 714 _constants->set_end(dest + BytesPerLong); |
693 | 715 *(jlong*) dest = Constant::primitive(constant); |
694 _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); | 716 |
695 TRACE_graal_3("relocating (%c) at %016x/%016x with destination at %016x (%d)", typeChar, instruction, operand, dest, size); | 717 long disp = dest - next_instruction; |
718 assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); | |
719 *((jint*) operand) = (jint) disp; | |
720 | |
721 _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); | |
722 TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size); | |
723 } | |
696 break; | 724 break; |
697 } | 725 } |
698 case 'a': { | 726 case 'a': { |
699 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); | 727 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); |
700 Handle obj = Constant::object(constant); | 728 Handle obj = Constant::object(constant); |
701 | 729 |
702 jobject value = JNIHandles::make_local(obj()); | 730 jobject value = JNIHandles::make_local(obj()); |
703 *((jobject*) operand) = value; | 731 *((jobject*) operand) = value; |
704 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); | 732 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); |
705 TRACE_graal_3("relocating (oop constant) at %016x/%016x", instruction, operand); | 733 TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand); |
706 break; | 734 break; |
707 } | 735 } |
708 default: | 736 default: |
709 fatal("unexpected Kind in DataPatch"); | 737 fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); |
710 break; | 738 break; |
711 } | 739 } |
712 } | 740 } |
713 | 741 |
714 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { | 742 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { |