Repository navigation
runtime interp invokedynamic_params
ceragon edited this page Jun 23, 2022
·
2 revisions
class ConstantPoolCache: public MetaspaceObj {
OopHandle _resolved_references;
Array<u2>* _reference_map;
void set_resolved_references(OopHandle s) {
_resolved_references = s;
}
};调用过程
class ConstantPool : public Metadata {
ConstantPoolCache* _cache;
void set_resolved_references(OopHandle s) {
_cache->set_resolved_references(s);
}
};void ConstantPool::initialize_resolved_references(ClassLoaderData* loader_data,
const intStack& reference_map,
int constant_pool_map_length,
TRAPS) {
// Initialized the resolved object cache.
int map_length = reference_map.length();
if (map_length > 0) {
objArrayOop stom = oopFactory::new_objArray(SystemDictionary::Object_klass(), map_length, CHECK);
Handle refs_handle (THREAD, (oop)stom);
set_resolved_references(loader_data->add_handle(refs_handle));
}
}void Rewriter::make_constant_pool_cache(TRAPS) {
ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data();
ConstantPoolCache* cache =
ConstantPoolCache::allocate(loader_data, _cp_cache_map,
_invokedynamic_cp_cache_map,
_invokedynamic_references_map, CHECK);
// 互相引用
_pool->set_cache(cache);
cache->set_constant_pool(_pool());
_pool->initialize_resolved_references(loader_data, _resolved_references_map,
_resolved_reference_limit,
THREAD);
}class Rewriter: public StackObj {
InstanceKlass* _klass;
constantPoolHandle _pool;
Array<Method*>* _methods;
GrowableArray<int> _cp_cache_map; // for Methodref, Fieldref,
// InterfaceMethodref and InvokeDynamic
GrowableArray<int> _reference_map; // maps from cp index to resolved_refs index (or -1)
GrowableArray<int> _resolved_references_map; // for strings, methodHandle, methodType
GrowableArray<int> _invokedynamic_references_map; // for invokedynamic resolved refs
GrowableArray<int> _method_handle_invokers;
int _resolved_reference_limit;
GrowableArray<int> _invokedynamic_cp_cache_map;
};
Rewriter::Rewriter(InstanceKlass* klass, const constantPoolHandle& cpool, Array<Method*>* methods, TRAPS)
:_klass(klass),
_pool(cpool),
_methods(methods),
_cp_cache_map(initial_size: cpool->length() / 2),
_invokedynamic_references_map(initial_size: cpool->length() / 2),
_invokedynamic_cp_cache_map(initial_size: cpool->length() / 4) {
rewrite_bytecodes(CHECK);
make_constant_pool_cache(THREAD);
}void Rewriter::rewrite(InstanceKlass* klass, TRAPS) {
Rewriter rw(klass, klass->constants(), klass->methods(), CHECK);
}void InstanceKlass::rewrite_class(TRAPS) {
Rewriter::rewrite(this, CHECK);
}由此可知,当链接一个类的时候,就会触发上面的逻辑
bool InstanceKlass::link_class_impl(bool throw_verifyerror, TRAPS) {
if (!is_linked()) {
if (!is_rewritten()) {
if (is_linked()) {
return true;
}
rewrite_class(CHECK_false);
}
}
}void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) {
// bcp 字节码的地址
// p 字节码后面参数的地址
address p = bcp + offset;
if (!reverse) {
// 从参数的地址中取出 参数
int cp_index = Bytes::get_Java_u2(p);
// cp_index 是 invokeDynamic 指令后面的参数,同时也是个常量池的索引
// cache_index
int cache_index = add_invokedynamic_cp_cache_entry(cp_index);
int resolved_index = add_invokedynamic_resolved_references_entries(cp_index, cache_index);
// 一种修正
Bytes::put_native_u4(p, ConstantPool::encode_invokedynamic_index(cache_index));
// 也就是说 bcp 和 ref 是一一对应的
_patch_invokedynamic_bcps->push(p);
_patch_invokedynamic_refs->push(resolved_index);
}
}
class Rewriter: public StackObj {
GrowableArray<int> _invokedynamic_cp_cache_map;
GrowableArray<int> _invokedynamic_references_map;
int add_invokedynamic_cp_cache_entry(int cp_index) {
int cache_index = _invokedynamic_cp_cache_map.append(cp_index);
return cache_index + _first_iteration_cp_cache_limit;
}
int add_invokedynamic_resolved_references_entries(int cp_index, int cache_index) {
int ref_index = -1;
for (int entry = 0; entry < ConstantPoolCacheEntry::_indy_resolved_references_entries; entry++) {
const int index = _resolved_references_map.append(cp_index);
if (entry == 0) {
ref_index = index;
}
_invokedynamic_references_map.at_put_grow(index, cache_index, -1);
}
return ref_index;
}
};