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) {