src/share/vm/oops/constantPool.hpp
Print this page
*** 83,93 ****
jobject _resolved_references;
Array<u2>* _reference_map;
enum {
_has_preresolution = 1, // Flags
! _on_stack = 2
};
int _flags; // old fashioned bit twiddling
int _length; // number of elements in the array
--- 83,94 ----
jobject _resolved_references;
Array<u2>* _reference_map;
enum {
_has_preresolution = 1, // Flags
! _on_stack = 2,
! _patched = 4
};
int _flags; // old fashioned bit twiddling
int _length; // number of elements in the array
*** 108,119 ****
int flags() const { return _flags; }
void set_flags(int f) { _flags = f; }
private:
! intptr_t* base() const { return (intptr_t*) (((char*) this) + sizeof(ConstantPool)); }
CPSlot slot_at(int which) {
assert(is_within_bounds(which), "index out of bounds");
// Uses volatile because the klass slot changes without a lock.
volatile intptr_t adr = (intptr_t)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which));
assert(adr != 0 || which == 0, "cp entry for klass should not be zero");
--- 109,128 ----
int flags() const { return _flags; }
void set_flags(int f) { _flags = f; }
private:
! intptr_t* base() const {
! // If the cp is patched then account for an optional pseudo-string map field
! return (intptr_t*) (((char*) this) + sizeof(ConstantPool) + (patched() ? sizeof(intptr_t) : 0));
! }
+ GrowableArray<u4>** pseudo_string_map_addr() {
+ // The pseudo-string map filed is optional, return NULL if the cp is not patched
+ return (GrowableArray<u4>**) (patched() ? (((char*) this) + sizeof(ConstantPool)) : NULL);
+ }
+
CPSlot slot_at(int which) {
assert(is_within_bounds(which), "index out of bounds");
// Uses volatile because the klass slot changes without a lock.
volatile intptr_t adr = (intptr_t)OrderAccess::load_ptr_acquire(obj_at_addr_raw(which));
assert(adr != 0 || which == 0, "cp entry for klass should not be zero");
*** 148,167 ****
jdouble* double_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return (jdouble*) &base()[which];
}
! ConstantPool(Array<u1>* tags);
ConstantPool() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
public:
! static ConstantPool* allocate(ClassLoaderData* loader_data, int length, TRAPS);
bool is_constantPool() const volatile { return true; }
Array<u1>* tags() const { return _tags; }
Array<u2>* operands() const { return _operands; }
bool has_preresolution() const { return (_flags & _has_preresolution) != 0; }
void set_has_preresolution() { _flags |= _has_preresolution; }
// Redefine classes support. If a method refering to this constant pool
// is on the executing stack, or as a handle in vm code, this constant pool
--- 157,223 ----
jdouble* double_at_addr(int which) const {
assert(is_within_bounds(which), "index out of bounds");
return (jdouble*) &base()[which];
}
! ConstantPool(Array<u1>* tags, bool patched);
ConstantPool() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); }
public:
! static ConstantPool* allocate(ClassLoaderData* loader_data, int length, bool patched, TRAPS);
bool is_constantPool() const volatile { return true; }
Array<u1>* tags() const { return _tags; }
Array<u2>* operands() const { return _operands; }
+ // The pseudo_string_map is optional filed.
+ // It is needed for JvmtiConstantPoolReconstituter.
+ // Map from a pseudo-string index to the original Utf8 entry index.
+ // Each u4 entry consist of two packed u2 integers:
+ // JVM_CONSTANT_String index and JVM_CONSTANT_Utf8 index
+
+ GrowableArray<u4>* pseudo_string_map() {
+ if (!patched()) {
+ return (GrowableArray<u4>*) NULL;
+ }
+ GrowableArray<u4>** addr = pseudo_string_map_addr();
+ if (*addr == NULL) {
+ *addr = new(ResourceObj::C_HEAP, mtClass) GrowableArray<u4>(1, true);
+ }
+ return *addr;
+ }
+
+ void map_pseudo_string_indices(u2 index, u2 utf8_idx) {
+ if (!patched()) {
+ return;
+ }
+ u4 packed = index << 16 | utf8_idx;
+ pseudo_string_map()->append(packed);
+ }
+
+ u2 get_pseudo_string_utf8_index(u2 index) {
+ if (!patched()) {
+ assert(false, "a pseudo-string map may exists for patched CP only");
+ return 0;
+ }
+ GrowableArray<u4>* map = pseudo_string_map();
+ int len = map->length();
+ // The entries are ordered by value so that a binary search can be
+ // used if a performance bottleneck is observed in this area.
+ for (int i = 0; i < len; i++) {
+ u4 packed = map->at(i);
+ u2 idx = (packed >> 16) & 0xFF;
+ if (idx == index) {
+ u2 utf8_idx = packed & 0xFF;
+ assert(utf8_idx > 0, "Utf8 index in pseudo-string map must be positive");
+ return utf8_idx;
+ }
+ }
+ assert(true, "not found a matching entry in pseudo-string map");
+ return 0;
+ }
+
bool has_preresolution() const { return (_flags & _has_preresolution) != 0; }
void set_has_preresolution() { _flags |= _has_preresolution; }
// Redefine classes support. If a method refering to this constant pool
// is on the executing stack, or as a handle in vm code, this constant pool
*** 168,177 ****
--- 224,237 ----
// can't be removed from the set of previous versions saved in the instance
// class.
bool on_stack() const { return (_flags &_on_stack) != 0; }
void set_on_stack(const bool value);
+ bool patched() const { return (_flags &_patched) != 0; }
+ void set_patched(const bool value) { if (value) _flags |= _patched;
+ else _flags &= ~_patched; }
+
// Klass holding pool
InstanceKlass* pool_holder() const { return _pool_holder; }
void set_pool_holder(InstanceKlass* k) { _pool_holder = k; }
InstanceKlass** pool_holder_addr() { return &_pool_holder; }