24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "asm/codeBuffer.hpp" |
26 #include "asm/codeBuffer.hpp" |
27 #include "asm/macroAssembler.hpp" |
27 #include "asm/macroAssembler.hpp" |
28 #include "asm/macroAssembler.inline.hpp" |
28 #include "asm/macroAssembler.inline.hpp" |
|
29 #include "gc/shared/collectedHeap.hpp" |
29 #include "runtime/atomic.hpp" |
30 #include "runtime/atomic.hpp" |
30 #include "runtime/icache.hpp" |
31 #include "runtime/icache.hpp" |
31 #include "runtime/os.hpp" |
32 #include "runtime/os.hpp" |
32 #include "runtime/thread.hpp" |
33 #include "runtime/thread.hpp" |
33 |
34 |
305 return code_section()->outer()->code_string(str); |
306 return code_section()->outer()->code_string(str); |
306 } |
307 } |
307 return NULL; |
308 return NULL; |
308 } |
309 } |
309 |
310 |
310 bool MacroAssembler::needs_explicit_null_check(intptr_t offset) { |
311 bool MacroAssembler::uses_implicit_null_check(void* address) { |
311 // Exception handler checks the nmethod's implicit null checks table |
312 // Exception handler checks the nmethod's implicit null checks table |
312 // only when this method returns false. |
313 // only when this method returns false. |
|
314 intptr_t int_address = reinterpret_cast<intptr_t>(address); |
|
315 intptr_t cell_header_size = Universe::heap()->cell_header_size(); |
|
316 size_t region_size = os::vm_page_size() + cell_header_size; |
313 #ifdef _LP64 |
317 #ifdef _LP64 |
314 if (UseCompressedOops && Universe::narrow_oop_base() != NULL) { |
318 if (UseCompressedOops && Universe::narrow_oop_base() != NULL) { |
315 assert (Universe::heap() != NULL, "java heap should be initialized"); |
319 // A SEGV can legitimately happen in C2 code at address |
316 // The first page after heap_base is unmapped and |
320 // (heap_base + offset) if Matcher::narrow_oop_use_complex_address |
317 // the 'offset' is equal to [heap_base + offset] for |
321 // is configured to allow narrow oops field loads to be implicitly |
318 // narrow oop implicit null checks. |
322 // null checked |
319 uintptr_t base = (uintptr_t)Universe::narrow_oop_base(); |
323 intptr_t start = ((intptr_t)Universe::narrow_oop_base()) - cell_header_size; |
320 if ((uintptr_t)offset >= base) { |
324 intptr_t end = start + region_size; |
321 // Normalize offset for the next check. |
325 if (int_address >= start && int_address < end) { |
322 offset = (intptr_t)(pointer_delta((void*)offset, (void*)base, 1)); |
326 return true; |
323 } |
327 } |
324 } |
328 } |
325 #endif |
329 #endif |
326 return offset < 0 || os::vm_page_size() <= offset; |
330 intptr_t start = -cell_header_size; |
327 } |
331 intptr_t end = start + region_size; |
|
332 return int_address >= start && int_address < end; |
|
333 } |
|
334 |
|
335 bool MacroAssembler::needs_explicit_null_check(intptr_t offset) { |
|
336 // Check if offset is outside of [-cell_header_size, os::vm_page_size) |
|
337 return offset < -Universe::heap()->cell_header_size() || |
|
338 offset >= os::vm_page_size(); |
|
339 } |