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:
Zachary Anderson 2016-07-18 10:39:09 -07:00
parent b30da81483
commit 43e89ccdd3
7 changed files with 44 additions and 41 deletions

View file

@ -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.

View file

@ -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:

View file

@ -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:

View file

@ -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)
}

View file

@ -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());
}

View file

@ -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();

View file

@ -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);