Mercurial > hg > graal-jvmci-8
comparison src/share/vm/c1x/c1x_CodeInstaller.cpp @ 1432:b61a43cd1255
sourcecode formatting
author | Lukas Stadler <lukas.stadler@oracle.com> |
---|---|
date | Wed, 01 Sep 2010 17:13:38 -0700 |
parents | abc670a709dc |
children | efba53f86c4f |
comparison
equal
deleted
inserted
replaced
1431:c01535d7fcc6 | 1432:b61a43cd1255 |
---|---|
20 * CA 95054 USA or visit www.sun.com if you need additional information or | 20 * CA 95054 USA or visit www.sun.com if you need additional information or |
21 * have any questions. | 21 * have any questions. |
22 * | 22 * |
23 */ | 23 */ |
24 | 24 |
25 | |
26 # include "incls/_precompiled.incl" | 25 # include "incls/_precompiled.incl" |
27 # include "incls/_c1x_CodeInstaller.cpp.incl" | 26 # include "incls/_c1x_CodeInstaller.cpp.incl" |
28 | 27 |
29 #define C1X_REGISTER_COUNT 32 | 28 #define C1X_REGISTER_COUNT 32 |
30 | 29 |
30 // convert c1x register indices (as used in oop maps) to hotspot registers | |
31 VMReg get_hotspot_reg(jint c1x_reg) { | 31 VMReg get_hotspot_reg(jint c1x_reg) { |
32 Register cpu_registers[] = { rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15 }; | 32 Register cpu_registers[] = { rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15 }; |
33 XMMRegister xmm_registers[] = { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 }; | 33 XMMRegister xmm_registers[] = { xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7, xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15 }; |
34 | 34 |
35 if (c1x_reg < 16) { | 35 if (c1x_reg < 16) { |
36 return cpu_registers[c1x_reg]->as_VMReg(); | 36 return cpu_registers[c1x_reg]->as_VMReg(); |
37 } else { | 37 } else { |
38 assert(c1x_reg < C1X_REGISTER_COUNT, "invalid register number"); | 38 assert(c1x_reg < C1X_REGISTER_COUNT, "invalid register number"); |
39 return xmm_registers[c1x_reg - 16]->as_VMReg(); | 39 return xmm_registers[c1x_reg - 16]->as_VMReg(); |
40 } | 40 } |
41 | 41 } |
42 } | 42 |
43 | 43 // creates a hotspot oop map out of the byte arrays provided by CiDebugInfo |
44 static OopMap* create_oop_map(jint frame_size, jint parameter_count, oop debug_info) { | 44 static OopMap* create_oop_map(jint frame_size, jint parameter_count, oop debug_info) { |
45 OopMap* map = new OopMap(frame_size, parameter_count); | 45 OopMap* map = new OopMap(frame_size, parameter_count); |
46 arrayOop register_map = (arrayOop)CiDebugInfo::registerRefMap(debug_info); | 46 arrayOop register_map = (arrayOop) CiDebugInfo::registerRefMap(debug_info); |
47 arrayOop frame_map = (arrayOop)CiDebugInfo::frameRefMap(debug_info); | 47 arrayOop frame_map = (arrayOop) CiDebugInfo::frameRefMap(debug_info); |
48 | 48 |
49 for (jint i=0; i<C1X_REGISTER_COUNT; i++) { | 49 for (jint i = 0; i < C1X_REGISTER_COUNT; i++) { |
50 unsigned char byte = ((unsigned char*)register_map->base(T_BYTE))[i / 8]; | 50 unsigned char byte = ((unsigned char*) register_map->base(T_BYTE))[i / 8]; |
51 bool is_oop = (byte & (1 << (i % 8))) != 0; | 51 bool is_oop = (byte & (1 << (i % 8))) != 0; |
52 VMReg reg = get_hotspot_reg(i); | 52 VMReg reg = get_hotspot_reg(i); |
53 if (is_oop) { | 53 if (is_oop) { |
54 map->set_oop(reg); | 54 map->set_oop(reg); |
55 } else { | 55 } else { |
56 map->set_value(reg); | 56 map->set_value(reg); |
57 } | 57 } |
58 } | 58 } |
59 | 59 |
60 for (jint i=0; i<frame_size; i++) { | 60 for (jint i = 0; i < frame_size; i++) { |
61 unsigned char byte = ((unsigned char*)frame_map->base(T_BYTE))[i / 8]; | 61 unsigned char byte = ((unsigned char*) frame_map->base(T_BYTE))[i / 8]; |
62 bool is_oop = (byte & (1 << (i % 8))) != 0; | 62 bool is_oop = (byte & (1 << (i % 8))) != 0; |
63 VMReg reg = VMRegImpl::stack2reg(i); | 63 VMReg reg = VMRegImpl::stack2reg(i); |
64 if (is_oop) { | 64 if (is_oop) { |
65 map->set_oop(reg); | 65 map->set_oop(reg); |
66 } else { | 66 } else { |
70 | 70 |
71 // TODO parameters? | 71 // TODO parameters? |
72 return map; | 72 return map; |
73 } | 73 } |
74 | 74 |
75 // TODO: finish this - c1x doesn't provide any scope values at the moment | |
75 static ScopeValue* get_hotspot_value(oop value) { | 76 static ScopeValue* get_hotspot_value(oop value) { |
76 fatal("not implemented"); | 77 fatal("not implemented"); |
77 if (value->is_a(CiRegisterValue::klass())) { | 78 if (value->is_a(CiRegisterValue::klass())) { |
78 TRACE_C1X_4("register value"); | 79 TRACE_C1X_4("register value"); |
79 IF_TRACE_C1X_4 value->print(); | 80 IF_TRACE_C1X_4 value->print(); |
83 } else { | 84 } else { |
84 ShouldNotReachHere(); | 85 ShouldNotReachHere(); |
85 } | 86 } |
86 } | 87 } |
87 | 88 |
88 | |
89 // constructor used to create a method | 89 // constructor used to create a method |
90 CodeInstaller::CodeInstaller(oop target_method) { | 90 CodeInstaller::CodeInstaller(oop target_method) { |
91 VM_ENTRY_MARK; | 91 VM_ENTRY_MARK; |
92 _env = CURRENT_ENV; | 92 _env = CURRENT_ENV; |
93 | 93 |
98 // TODO: This is a hack.. Produce correct entries. | 98 // TODO: This is a hack.. Produce correct entries. |
99 _offsets.set_value(CodeOffsets::Exceptions, 0); | 99 _offsets.set_value(CodeOffsets::Exceptions, 0); |
100 _offsets.set_value(CodeOffsets::Deopt, 0); | 100 _offsets.set_value(CodeOffsets::Deopt, 0); |
101 | 101 |
102 methodOop method = VmIds::get<methodOop>(HotSpotMethodResolved::vmId(_hotspot_method)); | 102 methodOop method = VmIds::get<methodOop>(HotSpotMethodResolved::vmId(_hotspot_method)); |
103 ciMethod *ciMethodObject = (ciMethod *)_env->get_object(method); | 103 ciMethod *ciMethodObject = (ciMethod *) _env->get_object(method); |
104 _parameter_count = method->size_of_parameters(); | 104 _parameter_count = method->size_of_parameters(); |
105 | 105 |
106 // (very) conservative estimate: each site needs a relocation | 106 // (very) conservative estimate: each site needs a relocation |
107 CodeBuffer buffer("temp c1x method", _total_size, _sites->length() * relocInfo::length_limit); | 107 CodeBuffer buffer("temp c1x method", _total_size, _sites->length() * relocInfo::length_limit); |
108 initialize_buffer(buffer); | 108 initialize_buffer(buffer); |
109 process_exception_handlers(); | 109 process_exception_handlers(); |
110 { | 110 { |
111 ThreadToNativeFromVM t((JavaThread*)THREAD); | 111 int stack_slots = (_frame_size / HeapWordSize) + 2; // conversion to words, need to add two slots for ret address and frame pointer |
112 _env->register_method(ciMethodObject, | 112 ThreadToNativeFromVM t((JavaThread*) THREAD); |
113 -1, | 113 _env->register_method(ciMethodObject, -1, &_offsets, 0, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, |
114 &_offsets, | 114 &_implicit_exception_table, C1XCompiler::instance(), _env->comp_level(), false, false); |
115 0, | |
116 &buffer, | |
117 (_frame_size / HeapWordSize) + 2, // conversion to words, need to add two slots for ret address and frame pointer | |
118 _debug_recorder->_oopmaps, | |
119 &_exception_handler_table, | |
120 &_implicit_exception_table, | |
121 C1XCompiler::instance(), | |
122 _env->comp_level(), | |
123 false, | |
124 false); | |
125 } | 115 } |
126 } | 116 } |
127 | 117 |
128 // constructor used to create a stub | 118 // constructor used to create a stub |
129 CodeInstaller::CodeInstaller(oop target_method, jlong& id) { | 119 CodeInstaller::CodeInstaller(oop target_method, jlong& id) { |
136 // (very) conservative estimate: each site needs a relocation | 126 // (very) conservative estimate: each site needs a relocation |
137 CodeBuffer buffer("temp c1x stub", _total_size, _sites->length() * relocInfo::length_limit); | 127 CodeBuffer buffer("temp c1x stub", _total_size, _sites->length() * relocInfo::length_limit); |
138 initialize_buffer(buffer); | 128 initialize_buffer(buffer); |
139 | 129 |
140 const char* cname = java_lang_String::as_utf8_string(_name); | 130 const char* cname = java_lang_String::as_utf8_string(_name); |
141 BufferBlob* blob = BufferBlob::create(strdup(cname), &buffer); // this is leaking strings... but only a limited number of stubs will be created | 131 BufferBlob* blob = BufferBlob::create(strdup(cname), &buffer); // this is leaking strings... but only a limited number of stubs will be created |
142 IF_TRACE_C1X_3 Disassembler::decode((CodeBlob*)blob); | 132 IF_TRACE_C1X_3 Disassembler::decode((CodeBlob*) blob); |
143 id = VmIds::addStub(blob->instructions_begin()); | 133 id = VmIds::addStub(blob->instructions_begin()); |
144 } | 134 } |
145 | 135 |
146 void CodeInstaller::initialize_fields(oop target_method) { | 136 void CodeInstaller::initialize_fields(oop target_method) { |
147 _citarget_method = HotSpotTargetMethod::targetMethod(target_method); | 137 _citarget_method = HotSpotTargetMethod::targetMethod(target_method); |
148 _hotspot_method = HotSpotTargetMethod::method(target_method); | 138 _hotspot_method = HotSpotTargetMethod::method(target_method); |
149 _name = HotSpotTargetMethod::name(target_method); | 139 _name = HotSpotTargetMethod::name(target_method); |
150 _sites = (arrayOop)HotSpotTargetMethod::sites(target_method); | 140 _sites = (arrayOop) HotSpotTargetMethod::sites(target_method); |
151 _exception_handlers = (arrayOop)HotSpotTargetMethod::exceptionHandlers(target_method); | 141 _exception_handlers = (arrayOop) HotSpotTargetMethod::exceptionHandlers(target_method); |
152 | 142 |
153 _code = (arrayOop)CiTargetMethod::targetCode(_citarget_method); | 143 _code = (arrayOop) CiTargetMethod::targetCode(_citarget_method); |
154 _code_size = CiTargetMethod::targetCodeSize(_citarget_method); | 144 _code_size = CiTargetMethod::targetCodeSize(_citarget_method); |
155 _frame_size = CiTargetMethod::frameSize(_citarget_method); | 145 _frame_size = CiTargetMethod::frameSize(_citarget_method); |
156 | 146 |
157 // (very) conservative estimate: each site needs a constant section entry | 147 // (very) conservative estimate: each site needs a constant section entry |
158 _constants_size = _sites->length() * BytesPerLong; | 148 _constants_size = _sites->length() * BytesPerLong; |
180 | 170 |
181 // copy the code into the newly created CodeBuffer | 171 // copy the code into the newly created CodeBuffer |
182 memcpy(_instructions->start(), _code->base(T_BYTE), _code_size); | 172 memcpy(_instructions->start(), _code->base(T_BYTE), _code_size); |
183 _instructions->set_end(_instructions->start() + _code_size); | 173 _instructions->set_end(_instructions->start() + _code_size); |
184 | 174 |
185 oop* sites = (oop*)_sites->base(T_OBJECT); | 175 oop* sites = (oop*) _sites->base(T_OBJECT); |
186 for (int i=0; i<_sites->length(); i++) { | 176 for (int i = 0; i < _sites->length(); i++) { |
187 oop site = sites[i]; | 177 oop site = sites[i]; |
188 jint pc_offset = CiTargetMethod_Site::pcOffset(site); | 178 jint pc_offset = CiTargetMethod_Site::pcOffset(site); |
189 | 179 |
190 if (site->is_a(CiTargetMethod_Safepoint::klass())) { | 180 if (site->is_a(CiTargetMethod_Safepoint::klass())) { |
191 TRACE_C1X_4("safepoint at %i", pc_offset); | 181 TRACE_C1X_4("safepoint at %i", pc_offset); |
206 } | 196 } |
207 | 197 |
208 void CodeInstaller::process_exception_handlers() { | 198 void CodeInstaller::process_exception_handlers() { |
209 // allocate some arrays for use by the collection code. | 199 // allocate some arrays for use by the collection code. |
210 const int num_handlers = 5; | 200 const int num_handlers = 5; |
211 GrowableArray<intptr_t>* bcis = new GrowableArray<intptr_t>(num_handlers); | 201 GrowableArray<intptr_t>* bcis = new GrowableArray<intptr_t> (num_handlers); |
212 GrowableArray<intptr_t>* scope_depths = new GrowableArray<intptr_t>(num_handlers); | 202 GrowableArray<intptr_t>* scope_depths = new GrowableArray<intptr_t> (num_handlers); |
213 GrowableArray<intptr_t>* pcos = new GrowableArray<intptr_t>(num_handlers); | 203 GrowableArray<intptr_t>* pcos = new GrowableArray<intptr_t> (num_handlers); |
214 | 204 |
215 if (_exception_handlers != NULL) { | 205 if (_exception_handlers != NULL) { |
216 oop* exception_handlers = (oop*)_exception_handlers->base(T_OBJECT); | 206 oop* exception_handlers = (oop*) _exception_handlers->base(T_OBJECT); |
217 for (int i=0; i<_exception_handlers->length(); i++) { | 207 for (int i = 0; i < _exception_handlers->length(); i++) { |
218 jint pc_offset = CiTargetMethod_Site::pcOffset(exception_handlers[i]); | 208 jint pc_offset = CiTargetMethod_Site::pcOffset(exception_handlers[i]); |
219 int start = i; | 209 int start = i; |
220 while ((i + 1)<_exception_handlers->length() && CiTargetMethod_Site::pcOffset(exception_handlers[i + 1]) == pc_offset) | 210 while ((i + 1) < _exception_handlers->length() && CiTargetMethod_Site::pcOffset(exception_handlers[i + 1]) == pc_offset) |
221 i ++; | 211 i++; |
222 | 212 |
223 // empty the arrays | 213 // empty the arrays |
224 bcis->trunc_to(0); | 214 bcis->trunc_to(0); |
225 scope_depths->trunc_to(0); | 215 scope_depths->trunc_to(0); |
226 pcos->trunc_to(0); | 216 pcos->trunc_to(0); |
254 scope_depths->append(scope_level); | 244 scope_depths->append(scope_level); |
255 } | 245 } |
256 pcos->append(handler_offset); | 246 pcos->append(handler_offset); |
257 | 247 |
258 // stop processing once we hit a catch any | 248 // stop processing once we hit a catch any |
259 // if (handler->is_catch_all()) { | 249 // if (handler->is_catch_all()) { |
260 // assert(i == handlers->length() - 1, "catch all must be last handler"); | 250 // assert(i == handlers->length() - 1, "catch all must be last handler"); |
261 // } | 251 // } |
262 | 252 |
263 } | 253 } |
264 _exception_handler_table.add_subtable(pc_offset, bcis, scope_depths, pcos); | 254 _exception_handler_table.add_subtable(pc_offset, bcis, scope_depths, pcos); |
265 } | 255 } |
266 } | 256 } |
267 | 257 |
268 | 258 } |
269 } | 259 |
270 | 260 void CodeInstaller::record_scope(jint pc_offset, oop code_pos, oop frame) { |
271 void CodeInstaller::record_frame(jint pc_offset, oop code_pos, oop frame) { | |
272 oop caller_pos = CiCodePos::caller(code_pos); | 261 oop caller_pos = CiCodePos::caller(code_pos); |
273 if (caller_pos != NULL) { | 262 if (caller_pos != NULL) { |
274 oop caller_frame = CiDebugInfo_Frame::caller(frame); | 263 oop caller_frame = CiDebugInfo_Frame::caller(frame); |
275 record_frame(pc_offset, caller_pos, caller_frame); | 264 record_scope(pc_offset, caller_pos, caller_frame); |
276 } else { | 265 } else { |
277 assert(frame == NULL || CiDebugInfo_Frame::caller(frame) == NULL, "unexpected layout - mismatching nesting of Frame and CiCodePos"); | 266 assert(frame == NULL || CiDebugInfo_Frame::caller(frame) == NULL, "unexpected layout - mismatching nesting of Frame and CiCodePos"); |
278 } | 267 } |
279 | 268 |
280 assert(frame == NULL || code_pos == CiDebugInfo_Frame::codePos(frame), "unexpected CiCodePos layout"); | 269 assert(frame == NULL || code_pos == CiDebugInfo_Frame::codePos(frame), "unexpected CiCodePos layout"); |
281 | 270 |
282 oop hotspot_method = CiCodePos::method(code_pos); | 271 oop hotspot_method = CiCodePos::method(code_pos); |
283 assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotMethodResolved::klass()), "unexpected hotspot method"); | 272 assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotMethodResolved::klass()), "unexpected hotspot method"); |
284 methodOop method = VmIds::get<methodOop>(HotSpotMethodResolved::vmId(hotspot_method)); | 273 methodOop method = VmIds::get<methodOop>(HotSpotMethodResolved::vmId(hotspot_method)); |
285 ciMethod *cimethod = (ciMethod *)_env->get_object(method); | 274 ciMethod *cimethod = (ciMethod *) _env->get_object(method); |
286 jint bci = CiCodePos::bci(code_pos); | 275 jint bci = CiCodePos::bci(code_pos); |
287 | 276 |
288 if (frame != NULL) { | 277 if (frame != NULL) { |
289 jint local_count = CiDebugInfo_Frame::numLocals(frame); | 278 jint local_count = CiDebugInfo_Frame::numLocals(frame); |
290 jint expression_count = CiDebugInfo_Frame::numStack(frame); | 279 jint expression_count = CiDebugInfo_Frame::numStack(frame); |
291 jint monitor_count = CiDebugInfo_Frame::numLocks(frame); | 280 jint monitor_count = CiDebugInfo_Frame::numLocks(frame); |
292 arrayOop values = (arrayOop)CiDebugInfo_Frame::values(frame); | 281 arrayOop values = (arrayOop) CiDebugInfo_Frame::values(frame); |
293 | 282 |
294 assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length"); | 283 assert(local_count + expression_count + monitor_count == values->length(), "unexpected values length"); |
295 assert(monitor_count == 0, "monitors not supported"); | 284 assert(monitor_count == 0, "monitors not supported"); |
296 | 285 |
297 GrowableArray<ScopeValue*>* locals = new GrowableArray<ScopeValue*>(); | 286 GrowableArray<ScopeValue*>* locals = new GrowableArray<ScopeValue*> (); |
298 GrowableArray<ScopeValue*>* expressions = new GrowableArray<ScopeValue*>(); | 287 GrowableArray<ScopeValue*>* expressions = new GrowableArray<ScopeValue*> (); |
299 GrowableArray<MonitorValue*>* monitors = new GrowableArray<MonitorValue*>(); | 288 GrowableArray<MonitorValue*>* monitors = new GrowableArray<MonitorValue*> (); |
300 | 289 |
301 for (jint i=0; i<values->length(); i++) { | 290 for (jint i = 0; i < values->length(); i++) { |
302 ScopeValue* value = get_hotspot_value(((oop*)values->base(T_OBJECT))[i]); | 291 ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i]); |
303 | 292 |
304 if (i < local_count) { | 293 if (i < local_count) { |
305 locals->append(value); | 294 locals->append(value); |
306 } else if (i < local_count + expression_count) { | 295 } else if (i < local_count + expression_count) { |
307 expressions->append(value); | 296 expressions->append(value); |
318 } else { | 307 } else { |
319 _debug_recorder->describe_scope(pc_offset, cimethod, bci, false, false, false, NULL, NULL, NULL); | 308 _debug_recorder->describe_scope(pc_offset, cimethod, bci, false, false, false, NULL, NULL, NULL); |
320 } | 309 } |
321 } | 310 } |
322 | 311 |
323 | |
324 void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { | 312 void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { |
325 oop debug_info = CiTargetMethod_Safepoint::debugInfo(site); | 313 oop debug_info = CiTargetMethod_Safepoint::debugInfo(site); |
326 assert(debug_info != NULL, "debug info expected"); | 314 assert(debug_info != NULL, "debug info expected"); |
327 | 315 |
328 // address instruction = _instructions->start() + pc_offset; | 316 // address instruction = _instructions->start() + pc_offset; |
329 // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start(); | 317 // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start(); |
330 _debug_recorder->add_safepoint(pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); | 318 _debug_recorder->add_safepoint(pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); |
331 | 319 |
332 oop code_pos = CiDebugInfo::codePos(debug_info); | 320 oop code_pos = CiDebugInfo::codePos(debug_info); |
333 oop frame = CiDebugInfo::frame(debug_info); | 321 oop frame = CiDebugInfo::frame(debug_info); |
334 record_frame(pc_offset, code_pos, frame); | 322 record_scope(pc_offset, code_pos, frame); |
335 | 323 |
336 _debug_recorder->end_safepoint(pc_offset); | 324 _debug_recorder->end_safepoint(pc_offset); |
337 } | 325 } |
338 | 326 |
339 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) { | 327 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, oop site) { |
341 oop hotspot_method = CiTargetMethod_Call::method(site); | 329 oop hotspot_method = CiTargetMethod_Call::method(site); |
342 oop symbol = CiTargetMethod_Call::symbol(site); | 330 oop symbol = CiTargetMethod_Call::symbol(site); |
343 oop global_stub = CiTargetMethod_Call::globalStubID(site); | 331 oop global_stub = CiTargetMethod_Call::globalStubID(site); |
344 | 332 |
345 oop debug_info = CiTargetMethod_Call::debugInfo(site); | 333 oop debug_info = CiTargetMethod_Call::debugInfo(site); |
346 arrayOop stack_map = (arrayOop)CiTargetMethod_Call::stackMap(site); | 334 arrayOop stack_map = (arrayOop) CiTargetMethod_Call::stackMap(site); |
347 arrayOop register_map = (arrayOop)CiTargetMethod_Call::registerMap(site); | 335 arrayOop register_map = (arrayOop) CiTargetMethod_Call::registerMap(site); |
348 | 336 |
349 assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (symbol ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type"); | 337 assert((runtime_call ? 1 : 0) + (hotspot_method ? 1 : 0) + (symbol ? 1 : 0) + (global_stub ? 1 : 0) == 1, "Call site needs exactly one type"); |
350 | 338 |
351 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); | 339 NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); |
352 jint next_pc_offset = pc_offset + NativeCall::instruction_size; | 340 jint next_pc_offset = pc_offset + NativeCall::instruction_size; |
353 | 341 |
354 if (debug_info != NULL) { | 342 if (debug_info != NULL) { |
355 _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); | 343 _debug_recorder->add_safepoint(next_pc_offset, create_oop_map(_frame_size, _parameter_count, debug_info)); |
356 oop code_pos = CiDebugInfo::codePos(debug_info); | 344 oop code_pos = CiDebugInfo::codePos(debug_info); |
357 oop frame = CiDebugInfo::frame(debug_info); | 345 oop frame = CiDebugInfo::frame(debug_info); |
358 record_frame(next_pc_offset, code_pos, frame); | 346 record_scope(next_pc_offset, code_pos, frame); |
359 } | 347 } |
360 | 348 |
361 if (runtime_call != NULL) { | 349 if (runtime_call != NULL) { |
362 if (runtime_call == CiRuntimeCall::Debug()) { | 350 if (runtime_call == CiRuntimeCall::Debug()) { |
363 TRACE_C1X_3("CiRuntimeCall::Debug()"); | 351 TRACE_C1X_3("CiRuntimeCall::Debug()"); |
384 } else { // method != NULL | 372 } else { // method != NULL |
385 assert(hotspot_method != NULL, "unexpected RiMethod"); | 373 assert(hotspot_method != NULL, "unexpected RiMethod"); |
386 assert(debug_info != NULL, "debug info expected"); | 374 assert(debug_info != NULL, "debug info expected"); |
387 | 375 |
388 methodOop method = NULL; | 376 methodOop method = NULL; |
389 if (hotspot_method->is_a(HotSpotMethodResolved::klass())) | 377 if (hotspot_method->is_a(HotSpotMethodResolved::klass())) method = VmIds::get<methodOop>(HotSpotMethodResolved::vmId(hotspot_method)); |
390 method = VmIds::get<methodOop>(HotSpotMethodResolved::vmId(hotspot_method)); | |
391 | 378 |
392 assert(debug_info != NULL, "debug info expected"); | 379 assert(debug_info != NULL, "debug info expected"); |
393 | 380 |
394 TRACE_C1X_3("method call"); | 381 TRACE_C1X_3("method call"); |
395 switch(_next_call_type) { | 382 switch (_next_call_type) { |
396 case MARK_INVOKEVIRTUAL: | 383 case MARK_INVOKEVIRTUAL: |
397 case MARK_INVOKEINTERFACE: { | 384 case MARK_INVOKEINTERFACE: { |
398 assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); | 385 assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); |
399 | 386 |
400 call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); | 387 call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); |
415 _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand); | 402 _instructions->relocate(call->instruction_address(), relocInfo::opt_virtual_call_type, Assembler::call32_operand); |
416 break; | 403 break; |
417 } | 404 } |
418 case MARK_INVOKE_INVALID: | 405 case MARK_INVOKE_INVALID: |
419 default: | 406 default: |
420 ShouldNotReachHere(); | 407 fatal("invalid _next_call_type value") |
421 break; | 408 break; |
422 } | 409 } |
423 } | 410 } |
424 _next_call_type = MARK_INVOKE_INVALID; | 411 _next_call_type = MARK_INVOKE_INVALID; |
425 if (debug_info != NULL) { | 412 if (debug_info != NULL) { |
431 oop constant = CiTargetMethod_DataPatch::constant(site); | 418 oop constant = CiTargetMethod_DataPatch::constant(site); |
432 oop kind = CiConstant::kind(constant); | 419 oop kind = CiConstant::kind(constant); |
433 | 420 |
434 address instruction = _instructions->start() + pc_offset; | 421 address instruction = _instructions->start() + pc_offset; |
435 | 422 |
436 switch(CiKind::typeChar(kind)) { | 423 switch (CiKind::typeChar(kind)) { |
437 case 'z': | 424 case 'z': |
438 case 'b': | 425 case 'b': |
439 case 's': | 426 case 's': |
440 case 'c': | 427 case 'c': |
441 case 'i': | 428 case 'i': |
442 fatal("int-sized values not expected in DataPatch"); | 429 fatal("int-sized values not expected in DataPatch") |
430 ; | |
443 break; | 431 break; |
444 case 'f': | 432 case 'f': |
445 case 'l': | 433 case 'l': |
446 case 'd': { | 434 case 'd': { |
447 address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); | 435 address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand); |
448 address next_instruction = Assembler::locate_next_instruction(instruction); | 436 address next_instruction = Assembler::locate_next_instruction(instruction); |
449 // we don't care if this is a long/double/etc., the primitive field contains the right bits | 437 // we don't care if this is a long/double/etc., the primitive field contains the right bits |
450 address dest = _constants->end(); | 438 address dest = _constants->end(); |
451 *(jlong*)dest = CiConstant::primitive(constant); | 439 *(jlong*) dest = CiConstant::primitive(constant); |
452 _constants->set_end(dest + BytesPerLong); | 440 _constants->set_end(dest + BytesPerLong); |
453 | 441 |
454 long disp = dest - next_instruction; | 442 long disp = dest - next_instruction; |
455 assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); | 443 assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); |
456 *((jint*)operand) = (jint)disp; | 444 *((jint*) operand) = (jint) disp; |
457 | 445 |
458 _instructions->relocate(instruction, section_word_Relocation::spec((address)dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); | 446 _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); |
459 TRACE_C1X_3("relocating (Float/Long/Double) at %016x/%016x", instruction, operand); | 447 TRACE_C1X_3("relocating (Float/Long/Double) at %016x/%016x", instruction, operand); |
460 break; | 448 break; |
461 } | 449 } |
462 case 'a': { | 450 case 'a': { |
463 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); | 451 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); |
464 oop obj = CiConstant::object(constant); | 452 oop obj = CiConstant::object(constant); |
465 | 453 |
466 if (obj->is_a(HotSpotTypeResolved::klass())) { | 454 if (obj->is_a(HotSpotTypeResolved::klass())) { |
467 *((jobject*)operand) = JNIHandles::make_local(VmIds::get<klassOop>(HotSpotTypeResolved::vmId(obj))); | 455 *((jobject*) operand) = JNIHandles::make_local(VmIds::get<klassOop>(HotSpotTypeResolved::vmId(obj))); |
468 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); | 456 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); |
469 TRACE_C1X_3("relocating (HotSpotType) at %016x/%016x", instruction, operand); | 457 TRACE_C1X_3("relocating (HotSpotType) at %016x/%016x", instruction, operand); |
470 } else { | 458 } else { |
471 assert(java_lang_boxing_object::is_instance(obj, T_LONG), "unexpected DataPatch object type"); | 459 assert(java_lang_boxing_object::is_instance(obj, T_LONG), "unexpected DataPatch object type"); |
472 jlong id = obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); | 460 jlong id = obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); |
474 assert((id & VmIds::TYPE_MASK) == VmIds::CONSTANT, "unexpected DataPatch type"); | 462 assert((id & VmIds::TYPE_MASK) == VmIds::CONSTANT, "unexpected DataPatch type"); |
475 | 463 |
476 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); | 464 address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); |
477 | 465 |
478 if (id == VmIds::DUMMY_CONSTANT) { | 466 if (id == VmIds::DUMMY_CONSTANT) { |
479 *((jobject*)operand) = (jobject)Universe::non_oop_word(); | 467 *((jobject*) operand) = (jobject) Universe::non_oop_word(); |
480 } else { | 468 } else { |
481 *((jobject*)operand) = JNIHandles::make_local(VmIds::get<oop>(id)); | 469 *((jobject*) operand) = JNIHandles::make_local(VmIds::get<oop>(id)); |
482 } | 470 } |
483 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); | 471 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); |
484 TRACE_C1X_3("relocating (oop constant) at %016x/%016x", instruction, operand); | 472 TRACE_C1X_3("relocating (oop constant) at %016x/%016x", instruction, operand); |
485 } | 473 } |
486 break; | 474 break; |
487 } | 475 } |
488 default: | 476 default: |
489 fatal("unexpected CiKind in DataPatch"); | 477 fatal("unexpected CiKind in DataPatch") |
490 break; | 478 break; |
491 } | 479 } |
492 } | 480 } |
493 | 481 |
494 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { | 482 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) { |
495 oop id_obj = CiTargetMethod_Mark::id(site); | 483 oop id_obj = CiTargetMethod_Mark::id(site); |
496 arrayOop references = (arrayOop)CiTargetMethod_Mark::references(site); | 484 arrayOop references = (arrayOop) CiTargetMethod_Mark::references(site); |
497 | 485 |
498 if (id_obj != NULL) { | 486 if (id_obj != NULL) { |
499 assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); | 487 assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); |
500 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); | 488 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); |
501 | 489 |
517 case MARK_EXCEPTION_HANDLER_ENTRY: | 505 case MARK_EXCEPTION_HANDLER_ENTRY: |
518 _offsets.set_value(CodeOffsets::Exceptions, pc_offset); | 506 _offsets.set_value(CodeOffsets::Exceptions, pc_offset); |
519 break; | 507 break; |
520 case MARK_STATIC_CALL_STUB: { | 508 case MARK_STATIC_CALL_STUB: { |
521 assert(references->length() == 1, "static call stub needs one reference"); | 509 assert(references->length() == 1, "static call stub needs one reference"); |
522 oop ref = ((oop*)references->base(T_OBJECT))[0]; | 510 oop ref = ((oop*) references->base(T_OBJECT))[0]; |
523 address call_pc = _instructions->start() + CiTargetMethod_Site::pcOffset(ref); | 511 address call_pc = _instructions->start() + CiTargetMethod_Site::pcOffset(ref); |
524 _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc)); | 512 _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc)); |
525 break; | 513 break; |
526 } | 514 } |
527 case MARK_INVOKE_INVALID: | 515 case MARK_INVOKE_INVALID: |
528 case MARK_INVOKEINTERFACE: | 516 case MARK_INVOKEINTERFACE: |
529 case MARK_INVOKESTATIC: | 517 case MARK_INVOKESTATIC: |
530 case MARK_INVOKESPECIAL: | 518 case MARK_INVOKESPECIAL: |
531 case MARK_INVOKEVIRTUAL: | 519 case MARK_INVOKEVIRTUAL: |
532 _next_call_type = (MarkId)id; | 520 _next_call_type = (MarkId) id; |
533 _invoke_mark_pc = instruction; | 521 _invoke_mark_pc = instruction; |
534 break; | 522 break; |
535 case MARK_IMPLICIT_NULL: | 523 case MARK_IMPLICIT_NULL: |
536 _implicit_exception_table.append(pc_offset, pc_offset); | 524 _implicit_exception_table.append(pc_offset, pc_offset); |
537 break; | 525 break; |
541 unsigned char* being_initialized_entry_offset = (unsigned char*) (instruction - 3); | 529 unsigned char* being_initialized_entry_offset = (unsigned char*) (instruction - 3); |
542 | 530 |
543 assert(*byte_skip == 5, "unexpected byte_skip"); | 531 assert(*byte_skip == 5, "unexpected byte_skip"); |
544 | 532 |
545 assert(references->length() == 2, "MARK_KLASS_PATCHING needs 2 references"); | 533 assert(references->length() == 2, "MARK_KLASS_PATCHING needs 2 references"); |
546 oop ref1 = ((oop*)references->base(T_OBJECT))[0]; | 534 oop ref1 = ((oop*) references->base(T_OBJECT))[0]; |
547 oop ref2 = ((oop*)references->base(T_OBJECT))[1]; | 535 oop ref2 = ((oop*) references->base(T_OBJECT))[1]; |
548 int i_byte_count = CiTargetMethod_Site::pcOffset(ref2) - CiTargetMethod_Site::pcOffset(ref1); | 536 int i_byte_count = CiTargetMethod_Site::pcOffset(ref2) - CiTargetMethod_Site::pcOffset(ref1); |
549 assert(i_byte_count == (unsigned char)i_byte_count, "invalid offset"); | 537 assert(i_byte_count == (unsigned char)i_byte_count, "invalid offset"); |
550 *byte_count = i_byte_count; | 538 *byte_count = i_byte_count; |
551 *being_initialized_entry_offset = *byte_count + *byte_skip; | 539 *being_initialized_entry_offset = *byte_count + *byte_skip; |
552 | 540 |
553 break; | 541 break; |
554 } | 542 } |
555 case MARK_DUMMY_OOP_RELOCATION: { | 543 case MARK_DUMMY_OOP_RELOCATION: { |
556 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); | 544 _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); |
557 | 545 |
558 RelocIterator iter(_instructions, (address)instruction, (address)(instruction + 1)); | 546 RelocIterator iter(_instructions, (address) instruction, (address) (instruction + 1)); |
559 relocInfo::change_reloc_info_for_address(&iter, (address) instruction, relocInfo::oop_type, relocInfo::none); | 547 relocInfo::change_reloc_info_for_address(&iter, (address) instruction, relocInfo::oop_type, relocInfo::none); |
560 break; | 548 break; |
561 } | 549 } |
562 default: | 550 default: |
563 ShouldNotReachHere(); | 551 ShouldNotReachHere() |
564 break; | 552 break; |
565 } | 553 } |
566 } | 554 } |
567 } | 555 } |
568 | 556 |
569 | |
570 | |
571 /* | |
572 if (_relocation_count > 0) { | |
573 jint* relocation_offsets = (jint*)((arrayOop)JNIHandles::resolve(_relocation_offsets))->base(T_INT); | |
574 oop* relocation_objects = (oop*)((arrayOop)JNIHandles::resolve(_relocation_data))->base(T_OBJECT); | |
575 | |
576 for (int i = 0; i < _relocation_count; i++) { | |
577 address inst = (address)instructions->start() + relocation_offsets[i]; | |
578 u_char inst_byte = *inst; | |
579 oop obj = relocation_objects[i]; | |
580 assert(obj != NULL, "NULL oop needn't be patched"); | |
581 | |
582 if (obj->is_a(SystemDictionary::HotSpotProxy_klass())) { | |
583 jlong id = com_sun_hotspot_c1x_HotSpotProxy::get_id(obj); | |
584 switch (id & VmIds::TYPE_MASK) { | |
585 case VmIds::CONSTANT: { | |
586 address operand = Assembler::locate_operand(inst, Assembler::imm_operand); | |
587 | |
588 *((jobject*)operand) = JNIHandles::make_local(VmIds::get<oop>(id)); | |
589 instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); | |
590 tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand); | |
591 break; | |
592 } | |
593 case VmIds::STUB: { | |
594 address operand = Assembler::locate_operand(inst, Assembler::call32_operand); | |
595 | |
596 long dest = (long)VmIds::getStub(id); | |
597 long disp = dest - (long)(operand + 4); | |
598 assert(disp == (int) disp, "disp doesn't fit in 32 bits"); | |
599 *((int*)operand) = (int)disp; | |
600 | |
601 instructions->relocate(inst, runtime_call_Relocation::spec(), Assembler::call32_operand); | |
602 tty->print_cr("relocating (Long) %02x at %016x/%016x", inst_byte, inst, operand); | |
603 break; | |
604 } | |
605 } | |
606 } else if (java_lang_boxing_object::is_instance(obj)) { | |
607 address operand = Assembler::locate_operand(inst, Assembler::disp32_operand); | |
608 long dest = (long)constants->end(); | |
609 if (java_lang_boxing_object::is_instance(obj, T_LONG)) { | |
610 // tty->print("relocate: %l\n", obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG))); | |
611 *(jlong*)constants->end() = obj->long_field(java_lang_boxing_object::value_offset_in_bytes(T_LONG)); | |
612 } else if (java_lang_boxing_object::is_instance(obj, T_DOUBLE)) { | |
613 // tty->print("relocate: %f\n", obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE))); | |
614 *(jdouble*)constants->end() = obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE)); | |
615 } else if (java_lang_boxing_object::is_instance(obj, T_FLOAT)) { | |
616 // tty->print("relocate: %f\n", obj->double_field(java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE))); | |
617 *(jfloat*)constants->end() = obj->float_field(java_lang_boxing_object::value_offset_in_bytes(T_FLOAT)); | |
618 } | |
619 constants->set_end(constants->end() + 8); | |
620 | |
621 long disp = dest - (long)(operand + 4); | |
622 assert(disp == (int) disp, "disp doesn't fit in 32 bits"); | |
623 *((int*)operand) = (int)disp; | |
624 | |
625 instructions->relocate(inst, section_word_Relocation::spec((address)dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); | |
626 tty->print_cr("relocating (Long/Double) %02x at %016x/%016x", inst_byte, inst, operand); | |
627 } else if (obj->is_a(_types.HotSpotTypeResolved)) { | |
628 address operand = Assembler::locate_operand(inst, Assembler::imm_operand); | |
629 | |
630 *((jobject*)operand) = JNIHandles::make_local(VmIds::get<klassOop>(obj->obj_field(_types.HotSpotTypeResolved_klassOop))); | |
631 instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); | |
632 tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand); | |
633 } else { | |
634 tty->print_cr("unknown relocation type"); | |
635 obj->print(); | |
636 } | |
637 } | |
638 }*/ | |
639 |