| 7091 | } |
| 7092 | |
| 7093 | void* compileVirtualMethod2(MyThread* t, GcClass* class_, unsigned index) |
| 7094 | { |
| 7095 | // If class_ has BootstrapFlag set, that means its vtable is not yet |
| 7096 | // available. However, we must set t->trace->targetMethod to an |
| 7097 | // appropriate method to ensure we can accurately scan the stack for |
| 7098 | // GC roots. We find such a method by looking for a superclass with |
| 7099 | // a vtable and using it instead: |
| 7100 | |
| 7101 | GcClass* c = class_; |
| 7102 | while (c->vmFlags() & BootstrapFlag) { |
| 7103 | c = c->super(); |
| 7104 | } |
| 7105 | t->trace->targetMethod |
| 7106 | = cast<GcMethod>(t, cast<GcArray>(t, c->virtualTable())->body()[index]); |
| 7107 | |
| 7108 | THREAD_RESOURCE0(t, static_cast<MyThread*>(t)->trace->targetMethod = 0;); |
| 7109 | |
| 7110 | PROTECT(t, class_); |
| 7111 | |
| 7112 | GcMethod* target = resolveTarget(t, class_, index); |
| 7113 | PROTECT(t, target); |
| 7114 | |
| 7115 | compile(t, codeAllocator(t), 0, target); |
| 7116 | |
| 7117 | void* address = reinterpret_cast<void*>(methodAddress(t, target)); |
| 7118 | if (target->flags() & ACC_NATIVE) { |
| 7119 | t->trace->nativeMethod = target; |
| 7120 | } else { |
| 7121 | class_->vtable()[target->offset()] = address; |
| 7122 | } |
| 7123 | return address; |
| 7124 | } |
| 7125 | |
| 7126 | uint64_t compileVirtualMethod(MyThread* t) |
| 7127 | { |
no test coverage detected