8200555: OopHandle should use Access API
Add RootAccess<> to OopHandle.resolve() in runtime and interpreter code. Add comments for compiler code for later. Reviewed-by: eosterlund, stefank
This commit is contained in:
parent
1b29264229
commit
1ee531afe9
@ -29,6 +29,9 @@
|
||||
#include "gc/g1/g1CardTable.hpp"
|
||||
#include "gc/g1/g1ThreadLocalData.hpp"
|
||||
#include "gc/g1/heapRegion.hpp"
|
||||
#include "gc/shared/collectedHeap.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
#include "interpreter/interp_masm.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
|
||||
|
@ -265,22 +265,21 @@ void InterpreterMacroAssembler::get_method_counters(Register method,
|
||||
|
||||
// Load object from cpool->resolved_references(index)
|
||||
void InterpreterMacroAssembler::load_resolved_reference_at_index(
|
||||
Register result, Register index) {
|
||||
Register result, Register index, Register tmp) {
|
||||
assert_different_registers(result, index);
|
||||
// convert from field index to resolved_references() index and from
|
||||
// word index to byte offset. Since this is a java object, it can be compressed
|
||||
Register tmp = index; // reuse
|
||||
lslw(tmp, tmp, LogBytesPerHeapOop);
|
||||
lslw(index, index, LogBytesPerHeapOop);
|
||||
|
||||
get_constant_pool(result);
|
||||
// load pointer for resolved_references[] objArray
|
||||
ldr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
|
||||
ldr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
|
||||
resolve_oop_handle(result);
|
||||
resolve_oop_handle(result, tmp);
|
||||
// Add in the index
|
||||
add(result, result, tmp);
|
||||
add(result, result, index);
|
||||
BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->load_at(this, IN_HEAP, T_OBJECT, result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), /*tmp1*/ noreg, /*tmp_thread*/ noreg);
|
||||
bs->load_at(this, IN_HEAP, T_OBJECT, result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp, /*tmp_thread*/ noreg);
|
||||
}
|
||||
|
||||
void InterpreterMacroAssembler::load_resolved_klass_at_offset(
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -122,7 +122,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
void get_method_counters(Register method, Register mcs, Label& skip);
|
||||
|
||||
// load cpool->resolved_references(index);
|
||||
void load_resolved_reference_at_index(Register result, Register index);
|
||||
void load_resolved_reference_at_index(Register result, Register index, Register tmp = r5);
|
||||
|
||||
// load cpool->resolved_klass_at(index);
|
||||
void load_resolved_klass_at_offset(Register cpool, Register index, Register klass, Register temp);
|
||||
|
@ -2108,7 +2108,7 @@ void MacroAssembler::resolve_jobject(Register value, Register thread, Register t
|
||||
|
||||
bind(not_weak);
|
||||
// Resolve (untagged) jobject.
|
||||
bs->load_at(this, IN_ROOT | ON_STRONG_OOP_REF, T_OBJECT,
|
||||
bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT,
|
||||
value, Address(value, 0), tmp, thread);
|
||||
verify_oop(value);
|
||||
bind(done);
|
||||
@ -3642,18 +3642,20 @@ void MacroAssembler::load_klass(Register dst, Register src) {
|
||||
}
|
||||
|
||||
// ((OopHandle)result).resolve();
|
||||
void MacroAssembler::resolve_oop_handle(Register result) {
|
||||
void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
|
||||
// OopHandle::resolve is an indirection.
|
||||
ldr(result, Address(result, 0));
|
||||
BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT,
|
||||
result, Address(result, 0), tmp, rthread);
|
||||
}
|
||||
|
||||
void MacroAssembler::load_mirror(Register dst, Register method) {
|
||||
void MacroAssembler::load_mirror(Register dst, Register method, Register tmp) {
|
||||
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
|
||||
ldr(dst, Address(rmethod, Method::const_offset()));
|
||||
ldr(dst, Address(dst, ConstMethod::constants_offset()));
|
||||
ldr(dst, Address(dst, ConstantPool::pool_holder_offset_in_bytes()));
|
||||
ldr(dst, Address(dst, mirror_offset));
|
||||
resolve_oop_handle(dst);
|
||||
resolve_oop_handle(dst, tmp);
|
||||
}
|
||||
|
||||
void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) {
|
||||
|
@ -803,8 +803,8 @@ public:
|
||||
void store_klass(Register dst, Register src);
|
||||
void cmp_klass(Register oop, Register trial_klass, Register tmp);
|
||||
|
||||
void resolve_oop_handle(Register result);
|
||||
void load_mirror(Register dst, Register method);
|
||||
void resolve_oop_handle(Register result, Register tmp = r5);
|
||||
void load_mirror(Register dst, Register method, Register tmp = r5);
|
||||
|
||||
void load_heap_oop(Register dst, Address src);
|
||||
|
||||
|
@ -739,20 +739,19 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, R
|
||||
|
||||
// Load object from cpool->resolved_references(index)
|
||||
void InterpreterMacroAssembler::load_resolved_reference_at_index(
|
||||
Register result, Register index) {
|
||||
assert_different_registers(result, index);
|
||||
Register result, Register index, Register tmp) {
|
||||
assert_different_registers(result, index, tmp);
|
||||
assert_not_delayed();
|
||||
// convert from field index to resolved_references() index and from
|
||||
// word index to byte offset. Since this is a java object, it can be compressed
|
||||
Register tmp = index; // reuse
|
||||
sll(index, LogBytesPerHeapOop, tmp);
|
||||
sll(index, LogBytesPerHeapOop, index);
|
||||
get_constant_pool(result);
|
||||
// load pointer for resolved_references[] objArray
|
||||
ld_ptr(result, ConstantPool::cache_offset_in_bytes(), result);
|
||||
ld_ptr(result, ConstantPoolCache::resolved_references_offset_in_bytes(), result);
|
||||
resolve_oop_handle(result);
|
||||
resolve_oop_handle(result, tmp);
|
||||
// Add in the index
|
||||
add(result, tmp, result);
|
||||
add(result, index, result);
|
||||
load_heap_oop(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT), result, tmp);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -183,7 +183,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
void get_cache_index_at_bcp(Register temp, Register index, int bcp_offset, size_t index_size = sizeof(u2));
|
||||
|
||||
// load cpool->resolved_references(index);
|
||||
void load_resolved_reference_at_index(Register result, Register index);
|
||||
void load_resolved_reference_at_index(Register result, Register index, Register tmp);
|
||||
|
||||
// load cpool->resolved_klass_at(index)
|
||||
void load_resolved_klass_at_offset(Register Rcpool, Register Roffset, Register Rklass);
|
||||
|
@ -3392,18 +3392,19 @@ void MacroAssembler::reserved_stack_check() {
|
||||
bind(no_reserved_zone_enabling);
|
||||
}
|
||||
// ((OopHandle)result).resolve();
|
||||
void MacroAssembler::resolve_oop_handle(Register result) {
|
||||
void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
|
||||
// OopHandle::resolve is an indirection.
|
||||
ld_ptr(result, 0, result);
|
||||
access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
|
||||
Address(result, 0), result, tmp);
|
||||
}
|
||||
|
||||
void MacroAssembler::load_mirror(Register mirror, Register method) {
|
||||
void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
|
||||
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
|
||||
ld_ptr(method, in_bytes(Method::const_offset()), mirror);
|
||||
ld_ptr(mirror, in_bytes(ConstMethod::constants_offset()), mirror);
|
||||
ld_ptr(mirror, ConstantPool::pool_holder_offset_in_bytes(), mirror);
|
||||
ld_ptr(mirror, mirror_offset, mirror);
|
||||
resolve_oop_handle(mirror);
|
||||
resolve_oop_handle(mirror, tmp);
|
||||
}
|
||||
|
||||
void MacroAssembler::load_klass(Register src_oop, Register klass) {
|
||||
|
@ -968,8 +968,8 @@ public:
|
||||
inline void ldbool(const Address& a, Register d);
|
||||
inline void movbool( bool boolconst, Register d);
|
||||
|
||||
void resolve_oop_handle(Register result);
|
||||
void load_mirror(Register mirror, Register method);
|
||||
void resolve_oop_handle(Register result, Register tmp);
|
||||
void load_mirror(Register mirror, Register method, Register tmp);
|
||||
|
||||
// klass oop manipulations if compressed
|
||||
void load_klass(Register src_oop, Register klass);
|
||||
|
@ -502,7 +502,7 @@ void TemplateInterpreterGenerator::lock_method() {
|
||||
__ delayed()->ld_ptr(Llocals, Interpreter::local_offset_in_bytes(0), O0); // get receiver for not-static case
|
||||
|
||||
// lock the mirror, not the Klass*
|
||||
__ load_mirror(O0, Lmethod);
|
||||
__ load_mirror(O0, Lmethod, Lscratch);
|
||||
|
||||
#ifdef ASSERT
|
||||
__ tst(O0);
|
||||
@ -810,7 +810,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
|
||||
__ mov( G5_method, Lmethod); // set Lmethod
|
||||
// Get mirror and store it in the frame as GC root for this Method*
|
||||
Register mirror = LcpoolCache;
|
||||
__ load_mirror(mirror, Lmethod);
|
||||
__ load_mirror(mirror, Lmethod, Lscratch);
|
||||
__ st_ptr(mirror, FP, (frame::interpreter_frame_mirror_offset * wordSize) + STACK_BIAS);
|
||||
__ get_constant_pool_cache(LcpoolCache); // set LcpoolCache
|
||||
__ sub(FP, rounded_vm_local_words * BytesPerWord, Lmonitors ); // set Lmonitors
|
||||
@ -1280,7 +1280,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||
// get native function entry point(O0 is a good temp until the very end)
|
||||
__ delayed()->ld_ptr(Lmethod, in_bytes(Method::native_function_offset()), O0);
|
||||
// for static methods insert the mirror argument
|
||||
__ load_mirror(O1, Lmethod);
|
||||
__ load_mirror(O1, Lmethod, G3_scratch);
|
||||
#ifdef ASSERT
|
||||
if (!PrintSignatureHandlers) // do not dirty the output with this
|
||||
{ Label L;
|
||||
|
@ -326,7 +326,7 @@ void TemplateTable::fast_aldc(bool wide) {
|
||||
// non-null object (CallSite, etc.)
|
||||
assert_different_registers(Otos_i, G3_scratch);
|
||||
__ get_cache_index_at_bcp(Otos_i, G3_scratch, 1, index_size); // load index => G3_scratch
|
||||
__ load_resolved_reference_at_index(Otos_i, G3_scratch);
|
||||
__ load_resolved_reference_at_index(Otos_i, G3_scratch, Lscratch);
|
||||
__ tst(Otos_i);
|
||||
__ br(Assembler::notEqual, false, Assembler::pt, resolved);
|
||||
__ delayed()->set((int)bytecode(), O1);
|
||||
@ -2016,7 +2016,7 @@ void TemplateTable::load_field_cp_cache_entry(Register Robj,
|
||||
Register Roffset,
|
||||
Register Rflags,
|
||||
bool is_static) {
|
||||
assert_different_registers(Rcache, Rflags, Roffset);
|
||||
assert_different_registers(Rcache, Rflags, Roffset, Lscratch);
|
||||
|
||||
ByteSize cp_base_offset = ConstantPoolCache::base_offset();
|
||||
|
||||
@ -2026,7 +2026,7 @@ void TemplateTable::load_field_cp_cache_entry(Register Robj,
|
||||
__ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::f1_offset(), Robj);
|
||||
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
|
||||
__ ld_ptr( Robj, mirror_offset, Robj);
|
||||
__ resolve_oop_handle(Robj);
|
||||
__ resolve_oop_handle(Robj, Lscratch);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2847,7 +2847,7 @@ void TemplateTable::prepare_invoke(int byte_no,
|
||||
// This must be done before we get the receiver,
|
||||
// since the parameter_size includes it.
|
||||
assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
|
||||
__ load_resolved_reference_at_index(temp, index);
|
||||
__ load_resolved_reference_at_index(temp, index, /*tmp*/recv);
|
||||
__ verify_oop(temp);
|
||||
__ push_ptr(temp); // push appendix (MethodType, CallSite, etc.)
|
||||
__ bind(L_no_push);
|
||||
|
@ -502,20 +502,19 @@ void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache,
|
||||
|
||||
// Load object from cpool->resolved_references(index)
|
||||
void InterpreterMacroAssembler::load_resolved_reference_at_index(
|
||||
Register result, Register index) {
|
||||
Register result, Register index, Register tmp) {
|
||||
assert_different_registers(result, index);
|
||||
// convert from field index to resolved_references() index and from
|
||||
// word index to byte offset. Since this is a java object, it can be compressed
|
||||
Register tmp = index; // reuse
|
||||
shll(tmp, LogBytesPerHeapOop);
|
||||
shll(index, LogBytesPerHeapOop);
|
||||
|
||||
get_constant_pool(result);
|
||||
// load pointer for resolved_references[] objArray
|
||||
movptr(result, Address(result, ConstantPool::cache_offset_in_bytes()));
|
||||
movptr(result, Address(result, ConstantPoolCache::resolved_references_offset_in_bytes()));
|
||||
resolve_oop_handle(result);
|
||||
resolve_oop_handle(result, tmp);
|
||||
// Add in the index
|
||||
addptr(result, tmp);
|
||||
addptr(result, index);
|
||||
load_heap_oop(result, Address(result, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), tmp);
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
size_t index_size = sizeof(u2));
|
||||
|
||||
// load cpool->resolved_references(index);
|
||||
void load_resolved_reference_at_index(Register result, Register index);
|
||||
void load_resolved_reference_at_index(Register result, Register index, Register tmp = rscratch2);
|
||||
|
||||
// load cpool->resolved_klass_at(index)
|
||||
void load_resolved_klass_at_index(Register cpool, // the constant pool (corrupted on return)
|
||||
|
@ -6274,19 +6274,22 @@ void MacroAssembler::restore_cpu_control_state_after_jni() {
|
||||
}
|
||||
|
||||
// ((OopHandle)result).resolve();
|
||||
void MacroAssembler::resolve_oop_handle(Register result) {
|
||||
// OopHandle::resolve is an indirection.
|
||||
movptr(result, Address(result, 0));
|
||||
void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
|
||||
// Only 64 bit platforms support GCs that require a tmp register
|
||||
// Only IN_HEAP loads require a thread_tmp register
|
||||
// OopHandle::resolve is an indirection like jobject.
|
||||
access_load_at(T_OBJECT, IN_ROOT | IN_CONCURRENT_ROOT,
|
||||
result, Address(result, 0), tmp, /*tmp_thread*/noreg);
|
||||
}
|
||||
|
||||
void MacroAssembler::load_mirror(Register mirror, Register method) {
|
||||
void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
|
||||
// get mirror
|
||||
const int mirror_offset = in_bytes(Klass::java_mirror_offset());
|
||||
movptr(mirror, Address(method, Method::const_offset()));
|
||||
movptr(mirror, Address(mirror, ConstMethod::constants_offset()));
|
||||
movptr(mirror, Address(mirror, ConstantPool::pool_holder_offset_in_bytes()));
|
||||
movptr(mirror, Address(mirror, mirror_offset));
|
||||
resolve_oop_handle(mirror);
|
||||
resolve_oop_handle(mirror, tmp);
|
||||
}
|
||||
|
||||
void MacroAssembler::load_klass(Register dst, Register src) {
|
||||
|
@ -307,8 +307,8 @@ class MacroAssembler: public Assembler {
|
||||
void movbool(Address dst, Register src);
|
||||
void testbool(Register dst);
|
||||
|
||||
void resolve_oop_handle(Register result);
|
||||
void load_mirror(Register mirror, Register method);
|
||||
void resolve_oop_handle(Register result, Register tmp = rscratch2);
|
||||
void load_mirror(Register mirror, Register method, Register tmp = rscratch2);
|
||||
|
||||
// oop manipulations
|
||||
void load_klass(Register dst, Register src);
|
||||
|
@ -64,6 +64,7 @@
|
||||
#include "memory/universe.hpp"
|
||||
#include "oops/access.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/oopHandle.inline.hpp"
|
||||
#include "oops/weakHandle.inline.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,6 +29,7 @@
|
||||
#include "classfile/moduleEntry.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/oopHandle.inline.hpp"
|
||||
#include "oops/symbol.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
@ -40,6 +41,8 @@
|
||||
|
||||
ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
|
||||
|
||||
oop ModuleEntry::module() const { return _module.resolve(); }
|
||||
|
||||
void ModuleEntry::set_location(Symbol* location) {
|
||||
if (_location != NULL) {
|
||||
// _location symbol's refcounts are managed by ModuleEntry,
|
||||
|
@ -90,7 +90,7 @@ public:
|
||||
Symbol* name() const { return literal(); }
|
||||
void set_name(Symbol* n) { set_literal(n); }
|
||||
|
||||
oop module() const { return _module.resolve(); }
|
||||
oop module() const;
|
||||
OopHandle module_handle() const { return _module; }
|
||||
void set_module(OopHandle j) { _module = j; }
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "code/compiledMethod.hpp"
|
||||
#include "code/nativeInst.hpp"
|
||||
#include "runtime/frame.hpp"
|
||||
#include "runtime/orderAccess.hpp"
|
||||
|
||||
inline bool CompiledMethod::is_deopt_pc(address pc) { return is_deopt_entry(pc) || is_deopt_mh_entry(pc); }
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define SHARE_VM_OOPS_CONSTANTPOOL_INLINE_HPP
|
||||
|
||||
#include "oops/constantPool.hpp"
|
||||
#include "oops/cpCache.inline.hpp"
|
||||
#include "runtime/orderAccess.inline.hpp"
|
||||
|
||||
inline CPSlot ConstantPool::slot_at(int which) const {
|
||||
|
@ -453,7 +453,7 @@ class ConstantPoolCache: public MetaspaceObj {
|
||||
oop archived_references() NOT_CDS_JAVA_HEAP_RETURN_(NULL);
|
||||
void set_archived_references(oop o) NOT_CDS_JAVA_HEAP_RETURN;
|
||||
|
||||
oop resolved_references() { return _resolved_references.resolve(); }
|
||||
inline oop resolved_references();
|
||||
void set_resolved_references(OopHandle s) { _resolved_references = s; }
|
||||
Array<u2>* reference_map() const { return _reference_map; }
|
||||
void set_reference_map(Array<u2>* o) { _reference_map = o; }
|
||||
|
@ -26,6 +26,7 @@
|
||||
#define SHARE_VM_OOPS_CPCACHEOOP_INLINE_HPP
|
||||
|
||||
#include "oops/cpCache.hpp"
|
||||
#include "oops/oopHandle.inline.hpp"
|
||||
#include "runtime/orderAccess.inline.hpp"
|
||||
|
||||
inline int ConstantPoolCacheEntry::indices_ord() const { return OrderAccess::load_acquire(&_indices); }
|
||||
@ -96,4 +97,6 @@ inline ConstantPoolCache::ConstantPoolCache(int length,
|
||||
}
|
||||
}
|
||||
|
||||
inline oop ConstantPoolCache::resolved_references() { return _resolved_references.resolve(); }
|
||||
|
||||
#endif // SHARE_VM_OOPS_CPCACHEOOP_INLINE_HPP
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/klass.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/oopHandle.inline.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/handles.inline.hpp"
|
||||
#include "runtime/orderAccess.inline.hpp"
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "oops/metadata.hpp"
|
||||
#include "oops/method.hpp"
|
||||
#include "oops/oop.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
#if INCLUDE_JVMCI
|
||||
#include "jvmci/jvmci_globals.hpp"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,8 +26,6 @@
|
||||
#define SHARE_VM_OOPS_OOPHANDLE_HPP
|
||||
|
||||
#include "oops/oop.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/orderAccess.hpp"
|
||||
|
||||
// Simple class for encapsulating oop pointers stored in metadata.
|
||||
// These are different from Handle. The Handle class stores pointers
|
||||
@ -45,7 +43,7 @@ public:
|
||||
OopHandle() : _obj(NULL) {}
|
||||
OopHandle(oop* w) : _obj(w) {}
|
||||
|
||||
oop resolve() const { return (_obj == NULL) ? (oop)NULL : *_obj; }
|
||||
inline oop resolve() const;
|
||||
|
||||
// Used only for removing handle.
|
||||
oop* ptr_raw() { return _obj; }
|
||||
|
36
src/hotspot/share/oops/oopHandle.inline.hpp
Normal file
36
src/hotspot/share/oops/oopHandle.inline.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_OOPS_OOPHANDLE_INLINE_HPP
|
||||
#define SHARE_VM_OOPS_OOPHANDLE_INLINE_HPP
|
||||
|
||||
#include "oops/access.inline.hpp"
|
||||
#include "oops/oopHandle.hpp"
|
||||
|
||||
inline oop OopHandle::resolve() const {
|
||||
return (_obj == NULL) ? (oop)NULL : RootAccess<IN_CONCURRENT_ROOT>::oop_load(_obj);
|
||||
}
|
||||
|
||||
#endif // SHARE_VM_OOPS_OOPHANDLE_INLINE_HPP
|
||||
|
@ -3488,6 +3488,7 @@ bool LibraryCallKit::inline_native_isInterrupted() {
|
||||
Node* LibraryCallKit::load_mirror_from_klass(Node* klass) {
|
||||
Node* p = basic_plus_adr(klass, in_bytes(Klass::java_mirror_offset()));
|
||||
Node* load = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
|
||||
// mirror = ((OopHandle)mirror)->resolve();
|
||||
return make_load(NULL, load, TypeInstPtr::MIRROR, T_OBJECT, MemNode::unordered);
|
||||
}
|
||||
|
||||
|
@ -2215,12 +2215,16 @@ Node* LoadNode::klass_identity_common(PhaseGVN* phase) {
|
||||
// mirror go completely dead. (Current exception: Class
|
||||
// mirrors may appear in debug info, but we could clean them out by
|
||||
// introducing a new debug info operator for Klass.java_mirror).
|
||||
//
|
||||
// If the code pattern requires a barrier for
|
||||
// mirror = ((OopHandle)mirror)->resolve();
|
||||
// this won't match.
|
||||
|
||||
if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass()
|
||||
&& offset == java_lang_Class::klass_offset_in_bytes()) {
|
||||
if (base->is_Load()) {
|
||||
Node* base2 = base->in(MemNode::Address);
|
||||
if (base2->is_Load()) { /* direct load of a load which is the oophandle */
|
||||
if (base2->is_Load()) { /* direct load of a load which is the OopHandle */
|
||||
Node* adr2 = base2->in(MemNode::Address);
|
||||
const TypeKlassPtr* tkls = phase->type(adr2)->isa_klassptr();
|
||||
if (tkls != NULL && !tkls->empty()
|
||||
|
@ -1628,8 +1628,11 @@ void PhaseIterGVN::add_users_to_worklist( Node *n ) {
|
||||
Node* imem = use->as_Initialize()->proj_out_or_null(TypeFunc::Memory);
|
||||
if (imem != NULL) add_users_to_worklist0(imem);
|
||||
}
|
||||
// Loading the java mirror from a klass oop requires two loads and the type
|
||||
// Loading the java mirror from a Klass requires two loads and the type
|
||||
// of the mirror load depends on the type of 'n'. See LoadNode::Value().
|
||||
// If the code pattern requires a barrier for
|
||||
// mirror = ((OopHandle)mirror)->resolve();
|
||||
// this won't match.
|
||||
if (use_op == Op_LoadP && use->bottom_type()->isa_rawptr()) {
|
||||
for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) {
|
||||
Node* u = use->fast_out(i2);
|
||||
@ -1774,8 +1777,11 @@ void PhaseCCP::analyze() {
|
||||
worklist.push(phi);
|
||||
}
|
||||
}
|
||||
// Loading the java mirror from a klass oop requires two loads and the type
|
||||
// Loading the java mirror from a Klass requires two loads and the type
|
||||
// of the mirror load depends on the type of 'n'. See LoadNode::Value().
|
||||
// If the code pattern requires a barrier for
|
||||
// mirror = ((OopHandle)mirror)->resolve();
|
||||
// this won't match.
|
||||
if (m_op == Op_LoadP && m->bottom_type()->isa_rawptr()) {
|
||||
for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
|
||||
Node* u = m->fast_out(i2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -886,7 +886,7 @@ static inline Node* isa_java_mirror_load(PhaseGVN* phase, Node* n) {
|
||||
if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL;
|
||||
|
||||
Node* adr = n->in(MemNode::Address);
|
||||
// First load from OopHandle
|
||||
// First load from OopHandle: ((OopHandle)mirror)->resolve(); may need barrier.
|
||||
if (adr->Opcode() != Op_LoadP || !phase->type(adr)->isa_rawptr()) return NULL;
|
||||
adr = adr->in(MemNode::Address);
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "oops/objArrayKlass.hpp"
|
||||
#include "oops/objArrayOop.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/oopHandle.inline.hpp"
|
||||
#include "prims/jvmtiEnvBase.hpp"
|
||||
#include "prims/jvmtiEventController.inline.hpp"
|
||||
#include "prims/jvmtiExtensions.hpp"
|
||||
@ -1478,6 +1479,13 @@ JvmtiMonitorClosure::do_monitor(ObjectMonitor* mon) {
|
||||
|
||||
GrowableArray<OopHandle>* JvmtiModuleClosure::_tbl = NULL;
|
||||
|
||||
void JvmtiModuleClosure::do_module(ModuleEntry* entry) {
|
||||
assert_locked_or_safepoint(Module_lock);
|
||||
OopHandle module = entry->module_handle();
|
||||
guarantee(module.resolve() != NULL, "module object is NULL");
|
||||
_tbl->push(module);
|
||||
}
|
||||
|
||||
jvmtiError
|
||||
JvmtiModuleClosure::get_all_modules(JvmtiEnv* env, jint* module_count_ptr, jobject** modules_ptr) {
|
||||
ResourceMark rm;
|
||||
|
@ -639,13 +639,7 @@ class JvmtiModuleClosure : public StackObj {
|
||||
private:
|
||||
static GrowableArray<OopHandle> *_tbl; // Protected with Module_lock
|
||||
|
||||
static void do_module(ModuleEntry* entry) {
|
||||
assert_locked_or_safepoint(Module_lock);
|
||||
OopHandle module = entry->module_handle();
|
||||
guarantee(module.resolve() != NULL, "module object is NULL");
|
||||
_tbl->push(module);
|
||||
}
|
||||
|
||||
static void do_module(ModuleEntry* entry);
|
||||
public:
|
||||
jvmtiError get_all_modules(JvmtiEnv* env, jint* module_count_ptr, jobject** modules_ptr);
|
||||
};
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
|
||||
#define SHARE_VM_RUNTIME_JAVAFRAMEANCHOR_HPP
|
||||
|
||||
#include "runtime/orderAccess.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "asm/assembler.hpp"
|
||||
#include "code/nmethod.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/extendedPC.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user