openjdk17 C++源码是怎么给java字段赋值的
##java源码
public class OtherClass {
public static int CONSTANT_O=9876;
public int o=1234;
public void dddd()
{
String dddd = "dddd";
//System.out.println(dddd);
System.out.println(dddd+CONSTANT_O);
}
}
public int o=1234;
在openjdk17中 C++源码怎么执行这段代码的,字节码sipush ,putfield #2
##字节码
public OtherClass();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: sipush 1234
8: putfield #2 // Field o:I
11: return
LineNumberTable:
line 1: 0
line 4: 4
##C++源码
// This function is the interface to the assembly code. It returns the resolved
// cpCache entry. This doesn't safepoint, but the helper routines safepoint.
// This function will check for redefinition!
JRT_ENTRY(void, InterpreterRuntime::resolve_from_cache(JavaThread* current, Bytecodes::Code bytecode)) {
switch (bytecode) {
case Bytecodes::_getstatic:
case Bytecodes::_putstatic:
case Bytecodes::_getfield:
case Bytecodes::_putfield:
resolve_get_put(current, bytecode);
break;
case Bytecodes::_invokevirtual:
case Bytecodes::_invokespecial:
case Bytecodes::_invokestatic:
case Bytecodes::_invokeinterface:
resolve_invoke(current, bytecode);
break;
case Bytecodes::_invokehandle:
resolve_invokehandle(current);
break;
case Bytecodes::_invokedynamic:
resolve_invokedynamic(current);
break;
default:
fatal("unexpected bytecode: %s", Bytecodes::name(bytecode));
break;
}
}
JRT_END
void InterpreterRuntime::resolve_get_put(JavaThread* current, Bytecodes::Code bytecode) {
// resolve field
fieldDescriptor info;
LastFrameAccessor last_frame(current);
constantPoolHandle pool(current, last_frame.method()->constants());
methodHandle m(current, last_frame.method());
bool is_put = (bytecode == Bytecodes::_putfield || bytecode == Bytecodes::_nofast_putfield ||
bytecode == Bytecodes::_putstatic);
bool is_static = (bytecode == Bytecodes::_getstatic || bytecode == Bytecodes::_putstatic);
{
JvmtiHideSingleStepping jhss(current);
JavaThread* THREAD = current; // For exception macros.
LinkResolver::resolve_field_access(info, pool, last_frame.get_index_u2_cpcache(bytecode),
m, bytecode, CHECK);
} // end JvmtiHideSingleStepping
// std::cout << "@@@@yym%%%%field" << info.name()->as_C_string() << ":offset:" << info.offset() << std::endl;
// check if link resolution caused cpCache to be updated
ConstantPoolCacheEntry* cp_cache_entry = last_frame.cache_entry();
if (cp_cache_entry->is_resolved(bytecode)) {
// std::cout << "@@@@yym%%%%field is_resolved" << info.name()->as_C_string() << ":result:" << "true" << std::endl;
return;
}
// compute auxiliary field attributes
TosState state = as_TosState(info.field_type());
// Resolution of put instructions on final fields is delayed. That is required so that
// exceptions are thrown at the correct place (when the instruction is actually invoked).
// If we do not resolve an instruction in the current pass, leaving the put_code
// set to zero will cause the next put instruction to the same field to reresolve.
// Resolution of put instructions to final instance fields with invalid updates (i.e.,
// to final instance fields with updates originating from a method different than <init>)
// is inhibited. A putfield instruction targeting an instance final field must throw
// an IllegalAccessError if the instruction is not in an instance
// initializer method <init>. If resolution were not inhibited, a putfield
// in an initializer method could be resolved in the initializer. Subsequent
// putfield instructions to the same field would then use cached information.
// As a result, those instructions would not pass through the VM. That is,
// checks in resolve_field_access() would not be executed for those instructions
// and the required IllegalAccessError would not be thrown.
//
// Also, we need to delay resolving getstatic and putstatic instructions until the
// class is initialized. This is required so that access to the static
// field will call the initialization function every time until the class
// is completely initialized ala. in 2.17.5 in JVM Specification.
InstanceKlass* klass = info.field_holder();
bool uninitialized_static = is_static && !klass->is_initialized();
bool has_initialized_final_update = info.field_holder()->major_version() >= 53 &&
info.has_initialized_final_update();
assert(!(has_initialized_final_update && !info.access_flags().is_final()), "Fields with initialized final updates must be final");
Bytecodes::Code get_code = (Bytecodes::Code)0;
Bytecodes::Code put_code = (Bytecodes::Code)0;
if (!uninitialized_static) {
get_code = ((is_static) ? Bytecodes::_getstatic : Bytecodes::_getfield);
if ((is_put && !has_initialized_final_update) || !info.access_flags().is_final()) {
put_code = ((is_static) ? Bytecodes::_putstatic : Bytecodes::_putfield);
}
}
// std::cout << "@@@@yym%%%%field" << info.name()->as_C_string() << ":offset:" << info.offset() << std::endl;
// std::string str1 = "o";
// const char* cStr = info.name()->as_klass_external_name();
// std::string str2(cStr); // 使用构造函数进行转换
// if (str1.compare(str2) == 0) {
// std::cout << "field name The strings are equal." << std::endl;
// std::cout << "@@@@yym%%%%field" << info.name()->as_C_string() << ":offset:" << info.offset() << std::endl;
// }
// std::string str3 = "CONSTANT_O";
// const char* cStr1 = info.name()->as_klass_external_name();
// std::string str4(cStr1); // 使用构造函数进行转换
// if (str3.compare(str4) == 0) {
// std::cout << "CONSTANT_O name The strings are equal." << std::endl;
// std::cout << "@@@@yym%%%%field" << info.name()->as_C_string() << ":offset:" << info.offset() << std::endl;
// }
cp_cache_entry->set_field(
get_code,
put_code,
info.field_holder(),
info.index(),
info.offset(),
state,
info.access_flags().is_final(),
info.access_flags().is_volatile()
);
}