mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 21:01:20 +00:00
DBC: Make unoptimized static calls call through ICData
Isolate reloading works by manipulating ICData. Unoptimized static calls won't go to the new function after a reload unless the calls go through the ICData. R=vegorov@google.com Review URL: https://codereview.chromium.org/2149993006 .
This commit is contained in:
parent
b30da81483
commit
43e89ccdd3
|
@ -190,34 +190,6 @@ cc/RegenerateAllocStubs: Skip
|
|||
cc/Debug_InspectStack_Optimized: Skip
|
||||
cc/Debug_InspectStackWithClosure_Optimized: Skip
|
||||
|
||||
# Isolate reload code assumes that all static calls have ICData attached to
|
||||
# them. However this is not the case on DBC.
|
||||
cc/IsolateReload_LiveStack: Skip
|
||||
cc/IsolateReload_StaticValuePreserved: Skip
|
||||
cc/IsolateReload_TopLevelFieldAdded: Skip
|
||||
cc/IsolateReload_ConstructorChanged: Skip
|
||||
cc/IsolateReload_ImplicitConstructorChanged: Skip
|
||||
cc/IsolateReload_MixinChanged: Skip
|
||||
cc/IsolateReload_SuperClassChanged: Skip
|
||||
cc/IsolateReload_ComplexInheritanceChange: Skip
|
||||
cc/IsolateReload_LibraryImportAdded: Skip
|
||||
cc/IsolateReload_LibraryHide: Skip
|
||||
cc/IsolateReload_LibraryLookup: Skip
|
||||
cc/IsolateReload_LibraryShow: Skip
|
||||
cc/IsolateReload_LiveStack: Skip
|
||||
cc/IsolateReload_StaticValuePreserved: Skip
|
||||
cc/IsolateReload_TopLevelFieldAdded: Skip
|
||||
cc/IsolateReload_ConstructorChanged: Skip
|
||||
cc/IsolateReload_ImplicitConstructorChanged: Skip
|
||||
cc/IsolateReload_MixinChanged: Skip
|
||||
cc/IsolateReload_SuperClassChanged: Skip
|
||||
cc/IsolateReload_ComplexInheritanceChange: Skip
|
||||
cc/IsolateReload_LibraryImportAdded: Skip
|
||||
cc/IsolateReload_LibraryHide: Skip
|
||||
cc/IsolateReload_LibraryLookup: Skip
|
||||
cc/IsolateReload_LibraryShow: Skip
|
||||
cc/IsolateReload_PendingSuperCall: Skip
|
||||
|
||||
[ $hot_reload ]
|
||||
dart/spawn_shutdown_test: Skip # We can shutdown an isolate before it reloads.
|
||||
dart/spawn_infinite_loop_test: Skip # We can shutdown an isolate before it reloads.
|
||||
|
|
|
@ -148,6 +148,11 @@ namespace dart {
|
|||
// Invoke function in SP[0] with arguments SP[-(1+ArgC)], ..., SP[-1] and
|
||||
// argument descriptor PP[D].
|
||||
//
|
||||
// - IndirectStaticCall ArgC, D
|
||||
//
|
||||
// Invoke the function given by the ICData in SP[0] with arguments
|
||||
// SP[-(1+ArgC)], ..., SP[-1] and argument descriptor PP[D].
|
||||
//
|
||||
// - InstanceCall<N> ArgC, D; InstanceCall<N>Opt ArgC, D
|
||||
//
|
||||
// Lookup and invoke method with N checked arguments using ICData in PP[D]
|
||||
|
@ -528,6 +533,7 @@ namespace dart {
|
|||
V(PushConstant, D, lit, ___, ___) \
|
||||
V(StoreLocal, X, xeg, ___, ___) \
|
||||
V(PopLocal, X, xeg, ___, ___) \
|
||||
V(IndirectStaticCall, A_D, num, num, ___) \
|
||||
V(StaticCall, A_D, num, num, ___) \
|
||||
V(InstanceCall1, A_D, num, num, ___) \
|
||||
V(InstanceCall2, A_D, num, num, ___) \
|
||||
|
@ -694,6 +700,7 @@ BYTECODES_LIST(DECLARE_BYTECODE)
|
|||
DART_FORCE_INLINE static bool IsCallOpcode(Instr instr) {
|
||||
switch (DecodeOpcode(instr)) {
|
||||
case Bytecode::kStaticCall:
|
||||
case Bytecode::kIndirectStaticCall:
|
||||
case Bytecode::kInstanceCall1:
|
||||
case Bytecode::kInstanceCall2:
|
||||
case Bytecode::kInstanceCall1Opt:
|
||||
|
|
|
@ -20,6 +20,7 @@ static bool HasLoadFromPool(Instr instr) {
|
|||
case Bytecode::kLoadConstant:
|
||||
case Bytecode::kPushConstant:
|
||||
case Bytecode::kStaticCall:
|
||||
case Bytecode::kIndirectStaticCall:
|
||||
case Bytecode::kInstanceCall1:
|
||||
case Bytecode::kInstanceCall2:
|
||||
case Bytecode::kInstanceCall1Opt:
|
||||
|
|
|
@ -3280,7 +3280,6 @@ LocationSummary* StaticCallInstr::MakeLocationSummary(Zone* zone,
|
|||
|
||||
|
||||
void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
#if !defined(TARGET_ARCH_DBC)
|
||||
const ICData* call_ic_data = NULL;
|
||||
if (!FLAG_propagate_ic_data || !compiler->is_optimizing() ||
|
||||
(ic_data() == NULL)) {
|
||||
|
@ -3306,6 +3305,8 @@ void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|||
} else {
|
||||
call_ic_data = &ICData::ZoneHandle(ic_data()->raw());
|
||||
}
|
||||
|
||||
#if !defined(TARGET_ARCH_DBC)
|
||||
compiler->GenerateStaticCall(deopt_id(),
|
||||
token_pos(),
|
||||
function(),
|
||||
|
@ -3321,17 +3322,20 @@ void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|||
Array::Handle(ic_data()->arguments_descriptor());
|
||||
const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor);
|
||||
|
||||
__ PushConstant(function());
|
||||
__ StaticCall(ArgumentCount(), argdesc_kidx);
|
||||
RawPcDescriptors::Kind kind = (compiler->is_optimizing())
|
||||
? RawPcDescriptors::kOther
|
||||
: RawPcDescriptors::kUnoptStaticCall;
|
||||
compiler->AddCurrentDescriptor(kind, deopt_id(), token_pos());
|
||||
|
||||
compiler->RecordAfterCall(this);
|
||||
|
||||
if (compiler->is_optimizing()) {
|
||||
__ PushConstant(function());
|
||||
__ StaticCall(ArgumentCount(), argdesc_kidx);
|
||||
compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
|
||||
deopt_id(), token_pos());
|
||||
compiler->RecordAfterCall(this);
|
||||
__ PopLocal(locs()->out(0).reg());
|
||||
} else {
|
||||
const intptr_t ic_data_kidx = __ AddConstant(*call_ic_data);
|
||||
__ PushConstant(ic_data_kidx);
|
||||
__ IndirectStaticCall(ArgumentCount(), argdesc_kidx);
|
||||
compiler->AddCurrentDescriptor(RawPcDescriptors::kUnoptStaticCall,
|
||||
deopt_id(), token_pos());
|
||||
compiler->RecordAfterCall(this);
|
||||
}
|
||||
#endif // !defined(TARGET_ARCH_DBC)
|
||||
}
|
||||
|
|
|
@ -400,7 +400,6 @@ EMIT_NATIVE_CODE(ClosureCall,
|
|||
compiler->assembler()->AddConstant(arguments_descriptor);
|
||||
__ StaticCall(argument_count, argdesc_kidx);
|
||||
compiler->RecordAfterCall(this);
|
||||
|
||||
if (compiler->is_optimizing()) {
|
||||
__ PopLocal(locs()->out(0).reg());
|
||||
}
|
||||
|
@ -702,7 +701,6 @@ EMIT_NATIVE_CODE(StringInterpolate,
|
|||
const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor);
|
||||
__ StaticCall(kArgumentCount, argdesc_kidx);
|
||||
compiler->RecordAfterCall(this);
|
||||
|
||||
if (compiler->is_optimizing()) {
|
||||
__ PopLocal(locs()->out(0).reg());
|
||||
}
|
||||
|
|
|
@ -737,6 +737,7 @@ void IsolateReloadContext::PostCommit() {
|
|||
set_saved_root_library(Library::Handle());
|
||||
set_saved_libraries(GrowableObjectArray::Handle());
|
||||
InvalidateWorld();
|
||||
TIR_Print("---- DONE COMMIT\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -909,6 +910,8 @@ class MarkFunctionsForRecompilation : public ObjectVisitor {
|
|||
|
||||
if (!stub_code) {
|
||||
if (clear_code) {
|
||||
VTIR_Print("Marking %s for recompilation, clearning code\n",
|
||||
func.ToCString());
|
||||
ClearAllCode(func);
|
||||
} else {
|
||||
PreserveUnoptimizedCode();
|
||||
|
@ -954,6 +957,7 @@ class MarkFunctionsForRecompilation : public ObjectVisitor {
|
|||
|
||||
void IsolateReloadContext::MarkAllFunctionsForRecompilation() {
|
||||
TIMELINE_SCOPE(MarkAllFunctionsForRecompilation);
|
||||
TIR_Print("---- MARKING ALL FUNCTIONS FOR RECOMPILATION\n");
|
||||
NoSafepointScope no_safepoint;
|
||||
HeapIterationScope heap_iteration_scope;
|
||||
MarkFunctionsForRecompilation visitor(isolate_, this);
|
||||
|
@ -962,6 +966,7 @@ void IsolateReloadContext::MarkAllFunctionsForRecompilation() {
|
|||
|
||||
|
||||
void IsolateReloadContext::InvalidateWorld() {
|
||||
TIR_Print("---- INVALIDATING WORLD\n");
|
||||
ResetMegamorphicCaches();
|
||||
DeoptimizeFunctionsOnStack();
|
||||
ResetUnoptimizedICsOnStack();
|
||||
|
|
|
@ -1374,7 +1374,7 @@ RawObject* Simulator::Call(const Code& code,
|
|||
}
|
||||
|
||||
{
|
||||
BYTECODE(StaticCall, A_D);
|
||||
BYTECODE(IndirectStaticCall, A_D);
|
||||
|
||||
// Check if single stepping.
|
||||
if (thread->isolate()->single_step()) {
|
||||
|
@ -1386,6 +1386,12 @@ RawObject* Simulator::Call(const Code& code,
|
|||
// Invoke target function.
|
||||
{
|
||||
const uint16_t argc = rA;
|
||||
// Lookup the funciton in the ICData.
|
||||
RawObject* ic_data_obj = SP[0];
|
||||
RawICData* ic_data = RAW_CAST(ICData, ic_data_obj);
|
||||
RawArray* cache = ic_data->ptr()->ic_data_->ptr();
|
||||
SP[0] = cache->data()[ICData::TargetIndexFor(
|
||||
ic_data->ptr()->state_bits_ & 0x3)];
|
||||
RawObject** call_base = SP - argc;
|
||||
RawObject** call_top = SP; // *SP contains function
|
||||
argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD));
|
||||
|
@ -1395,6 +1401,16 @@ RawObject* Simulator::Call(const Code& code,
|
|||
DISPATCH();
|
||||
}
|
||||
|
||||
{
|
||||
BYTECODE(StaticCall, A_D);
|
||||
const uint16_t argc = rA;
|
||||
RawObject** call_base = SP - argc;
|
||||
RawObject** call_top = SP; // *SP contains function
|
||||
argdesc = static_cast<RawArray*>(LOAD_CONSTANT(rD));
|
||||
Invoke(thread, call_base, call_top, &pp, &pc, &FP, &SP);
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
{
|
||||
BYTECODE(InstanceCall1, A_D);
|
||||
|
||||
|
|
Loading…
Reference in a new issue