Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Unified Diff: runtime/vm/simulator_dbc.cc

Issue 1992963002: Enable optimizer pipeline for DBC. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/simulator_dbc.h ('k') | runtime/vm/stack_frame.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/simulator_dbc.cc
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index e732409bc749e76ffacdcc5c2ef6d5f3a8a0613f..ffe4e9285c7f38ef50cbac33b65e2daccf027b2b 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -87,24 +87,26 @@ DART_FORCE_INLINE static RawObject** SavedCallerFP(RawObject** FP) {
}
-DART_FORCE_INLINE static RawCode* FrameCode(RawObject** FP) {
- return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]);
-}
-
-
-DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) {
- FP[kPcMarkerSlotFromFp] = code;
-}
-
-
DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP,
intptr_t argc) {
return FP - (kDartFrameFixedSize + argc);
}
+#define RAW_CAST(Type, val) (SimulatorHelpers::CastTo##Type(val))
+
+
class SimulatorHelpers {
public:
+#define DEFINE_CASTS(Type) \
+ DART_FORCE_INLINE static Raw##Type* CastTo##Type(RawObject* obj) { \
+ ASSERT((k##Type##Cid == kSmiCid) ? !obj->IsHeapObject() \
+ : obj->Is##Type()); \
+ return reinterpret_cast<Raw##Type*>(obj); \
+ }
+ CLASS_LIST(DEFINE_CASTS)
+#undef DEFINE_CASTS
+
DART_FORCE_INLINE static RawSmi* GetClassIdAsSmi(RawObject* obj) {
return Smi::New(obj->IsHeapObject() ? obj->GetClassId()
: static_cast<intptr_t>(kSmiCid));
@@ -115,10 +117,8 @@ class SimulatorHelpers {
: static_cast<intptr_t>(kSmiCid);
}
- DART_FORCE_INLINE static void IncrementUsageCounter(RawICData* icdata) {
- reinterpret_cast<RawFunction*>(icdata->ptr()->owner_)
- ->ptr()
- ->usage_counter_++;
+ DART_FORCE_INLINE static void IncrementUsageCounter(RawFunction* f) {
+ f->ptr()->usage_counter_++;
}
DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs,
@@ -226,6 +226,17 @@ class SimulatorHelpers {
}
return false;
}
+
+ DART_FORCE_INLINE static RawCode* FrameCode(RawObject** FP) {
+ ASSERT(GetClassId(FP[kPcMarkerSlotFromFp]) == kCodeCid);
+ return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]);
+ }
+
+
+ DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) {
+ ASSERT(GetClassId(code) == kCodeCid);
+ FP[kPcMarkerSlotFromFp] = code;
+ }
};
@@ -482,6 +493,26 @@ void Simulator::CallRuntime(Thread* thread,
}
+DART_FORCE_INLINE static void EnterSyntheticFrame(RawObject*** FP,
+ RawObject*** SP,
+ uint32_t* pc) {
+ RawObject** fp = *SP + kDartFrameFixedSize;
+ fp[kPcMarkerSlotFromFp] = 0;
+ fp[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(pc);
+ fp[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP);
+ *FP = fp;
+ *SP = fp - 1;
+}
+
+
+DART_FORCE_INLINE static void LeaveSyntheticFrame(RawObject*** FP,
+ RawObject*** SP) {
+ RawObject** fp = *FP;
+ *FP = reinterpret_cast<RawObject**>(fp[kSavedCallerFpSlotFromFp]);
+ *SP = fp - kDartFrameFixedSize;
+}
+
+
DART_FORCE_INLINE void Simulator::Invoke(Thread* thread,
RawObject** call_base,
RawObject** call_top,
@@ -557,7 +588,6 @@ DART_FORCE_INLINE void Simulator::InstanceCall1(Thread* thread,
RawObject*** FP,
RawObject*** SP) {
ASSERT(icdata->GetClassId() == kICDataCid);
- SimulatorHelpers::IncrementUsageCounter(icdata);
const intptr_t kCheckedArgs = 1;
RawObject** args = call_base;
@@ -596,7 +626,6 @@ DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread,
RawObject*** FP,
RawObject*** SP) {
ASSERT(icdata->GetClassId() == kICDataCid);
- SimulatorHelpers::IncrementUsageCounter(icdata);
const intptr_t kCheckedArgs = 2;
RawObject** args = call_base;
@@ -627,49 +656,6 @@ DART_FORCE_INLINE void Simulator::InstanceCall2(Thread* thread,
}
-DART_FORCE_INLINE void Simulator::InstanceCall3(Thread* thread,
- RawICData* icdata,
- RawObject** call_base,
- RawObject** top,
- RawArray** argdesc,
- RawObjectPool** pp,
- uint32_t** pc,
- RawObject*** FP,
- RawObject*** SP) {
- ASSERT(icdata->GetClassId() == kICDataCid);
- SimulatorHelpers::IncrementUsageCounter(icdata);
-
- const intptr_t kCheckedArgs = 3;
- RawObject** args = call_base;
- RawArray* cache = icdata->ptr()->ic_data_->ptr();
-
- RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]);
- RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]);
- RawSmi* arg1_cid = SimulatorHelpers::GetClassIdAsSmi(args[2]);
-
- bool found = false;
- const intptr_t length = Smi::Value(cache->length_);
- for (intptr_t i = 0;
- i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
- if ((cache->data()[i + 0] == receiver_cid) &&
- (cache->data()[i + 1] == arg0_cid) &&
- (cache->data()[i + 2] == arg1_cid)) {
- top[0] = cache->data()[i + kCheckedArgs];
- found = true;
- break;
- }
- }
-
- if (!found) {
- InlineCacheMiss(
- kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP);
- }
-
- *argdesc = icdata->ptr()->args_descriptor_;
- Invoke(thread, call_base, top, pp, pc, FP, SP);
-}
-
-
// Note: functions below are marked DART_NOINLINE to recover performance on
// ARM where inlining these functions into the interpreter loop seemed to cause
// some code quality issues.
@@ -801,7 +787,7 @@ static DART_NOINLINE bool InvokeNativeWrapper(
thread->set_vm_tag(vm_tag); \
return special_[kExceptionSpecialIndex]; \
} \
- pp = FrameCode(FP)->ptr()->object_pool_->ptr(); \
+ pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); \
goto DispatchAfterException; \
} while (0) \
@@ -950,7 +936,29 @@ RawObject* Simulator::Call(const Code& code,
}
{
- BYTECODE(EntryOpt, A_B_C);
+ BYTECODE(EntryOptimized, A_D);
+ const uint8_t num_fixed_params = rA;
+ const uint16_t num_registers = rD;
+
+ // Decode arguments descriptor.
+ const intptr_t pos_count = Smi::Value(*reinterpret_cast<RawSmi**>(
+ reinterpret_cast<uword>(argdesc->ptr()) +
+ Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex)));
+
+ // Check that we got the right number of positional parameters.
+ if (pos_count != num_fixed_params) {
+ // Mismatch can only occur if current function is a closure.
+ goto ClosureNoSuchMethod;
+ }
+
+ // Reserve space for registers used by the optimized code.
+ SP = FP + num_registers - 1;
+
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(EntryOptional, A_B_C);
const uint16_t num_fixed_params = rA;
const uint16_t num_opt_pos_params = rB;
const uint16_t num_opt_named_params = rC;
@@ -1098,7 +1106,7 @@ RawObject* Simulator::Call(const Code& code,
{
// Function should be compiled now, dispatch to its entry point.
RawCode* code = FrameFunction(FP)->ptr()->code_;
- SetFrameCode(FP, code);
+ SimulatorHelpers::SetFrameCode(FP, code);
pp = code->ptr()->object_pool_->ptr();
pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_);
}
@@ -1106,6 +1114,36 @@ RawObject* Simulator::Call(const Code& code,
}
{
+ BYTECODE(HotCheck, A_D);
+ const uint8_t increment = rA;
+ const uint16_t threshold = rD;
+ RawFunction* f = FrameFunction(FP);
+ int32_t counter = f->ptr()->usage_counter_;
+ // Note: we don't increment usage counter in the prologue of optimized
+ // functions.
+ if (increment) {
+ counter += increment;
+ f->ptr()->usage_counter_ = counter;
+ }
+ if (counter >= threshold) {
+ FP[0] = f;
+ FP[1] = 0;
+ Exit(thread, FP, FP + 2, pc);
+ NativeArguments args(thread, 1, FP, FP + 1);
+ INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, args);
+ {
+ // DRT_OptimizeInvokedFunction returns the code object to execute.
+ ASSERT(FP[1]->GetClassId() == kCodeCid);
+ RawCode* code = static_cast<RawCode*>(FP[1]);
+ SimulatorHelpers::SetFrameCode(FP, code);
+ pp = code->ptr()->object_pool_->ptr();
+ pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_);
+ }
+ }
+ DISPATCH();
+ }
+
+ {
BYTECODE(CheckStack, A);
{
if (reinterpret_cast<uword>(SP) >= thread->stack_limit()) {
@@ -1259,6 +1297,14 @@ RawObject* Simulator::Call(const Code& code,
}
{
+ BYTECODE(Swap, A_X);
+ RawObject* tmp = FP[rD];
+ FP[rD] = FP[rA];
+ FP[rA] = tmp;
+ DISPATCH();
+ }
+
+ {
BYTECODE(StoreLocal, A_X);
FP[rD] = *SP;
DISPATCH();
@@ -1283,6 +1329,12 @@ RawObject* Simulator::Call(const Code& code,
}
{
+ BYTECODE(BooleanNegate, A_D);
+ FP[rA] = (FP[rD] == true_value) ? false_value : true_value;
+ DISPATCH();
+ }
+
+ {
BYTECODE(StaticCall, A_D);
// Check if single stepping.
@@ -1305,7 +1357,7 @@ RawObject* Simulator::Call(const Code& code,
}
{
- BYTECODE(InstanceCall, A_D);
+ BYTECODE(InstanceCall1, A_D);
// Check if single stepping.
if (thread->isolate()->single_step()) {
@@ -1320,9 +1372,12 @@ RawObject* Simulator::Call(const Code& code,
RawObject** call_base = SP - argc + 1;
RawObject** call_top = SP + 1;
- InstanceCall1(thread,
- static_cast<RawICData*>(LOAD_CONSTANT(kidx)),
- call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+
+ RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
+ SimulatorHelpers::IncrementUsageCounter(
+ RAW_CAST(Function, icdata->ptr()->owner_));
+ InstanceCall1(
+ thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
}
DISPATCH();
@@ -1342,31 +1397,50 @@ RawObject* Simulator::Call(const Code& code,
RawObject** call_base = SP - argc + 1;
RawObject** call_top = SP + 1;
- InstanceCall2(thread,
- static_cast<RawICData*>(LOAD_CONSTANT(kidx)),
- call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+
+ RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
+ SimulatorHelpers::IncrementUsageCounter(
+ RAW_CAST(Function, icdata->ptr()->owner_));
+ InstanceCall2(
+ thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
}
DISPATCH();
}
{
- BYTECODE(InstanceCall3, A_D);
- if (thread->isolate()->single_step()) {
- Exit(thread, FP, SP + 1, pc);
- NativeArguments args(thread, 0, NULL, NULL);
- INVOKE_RUNTIME(DRT_SingleStepHandler, args);
+ BYTECODE(InstanceCall1Opt, A_D);
+
+ {
+ const uint16_t argc = rA;
+ const uint16_t kidx = rD;
+
+ RawObject** call_base = SP - argc + 1;
+ RawObject** call_top = SP + 1;
+
+ RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
+ SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP));
+ InstanceCall1(
+ thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
}
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(InstanceCall2Opt, A_D);
+
{
const uint16_t argc = rA;
const uint16_t kidx = rD;
RawObject** call_base = SP - argc + 1;
RawObject** call_top = SP + 1;
- InstanceCall3(thread,
- static_cast<RawICData*>(LOAD_CONSTANT(kidx)),
- call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+
+ RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
+ SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP));
+ InstanceCall2(
+ thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
}
DISPATCH();
@@ -1495,7 +1569,7 @@ RawObject* Simulator::Call(const Code& code,
// Restore SP, FP and PP. Push result and dispatch.
SP = FrameArguments(FP, argc);
FP = SavedCallerFP(FP);
- pp = FrameCode(FP)->ptr()->object_pool_->ptr();
+ pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
*SP = result;
DISPATCH();
}
@@ -1740,7 +1814,7 @@ RawObject* Simulator::Call(const Code& code,
}
{
- BYTECODE(IfEqStrictTOS, A_D);
+ BYTECODE(IfEqStrictTOS, 0);
SP -= 2;
if (SP[1] != SP[2]) {
pc++;
@@ -1749,7 +1823,7 @@ RawObject* Simulator::Call(const Code& code,
}
{
- BYTECODE(IfNeStrictTOS, A_D);
+ BYTECODE(IfNeStrictTOS, 0);
SP -= 2;
if (SP[1] == SP[2]) {
pc++;
@@ -1758,7 +1832,7 @@ RawObject* Simulator::Call(const Code& code,
}
{
- BYTECODE(IfEqStrictNumTOS, A_D);
+ BYTECODE(IfEqStrictNumTOS, 0);
if (thread->isolate()->single_step()) {
Exit(thread, FP, SP + 1, pc);
NativeArguments args(thread, 0, NULL, NULL);
@@ -1773,7 +1847,7 @@ RawObject* Simulator::Call(const Code& code,
}
{
- BYTECODE(IfNeStrictNumTOS, A_D);
+ BYTECODE(IfNeStrictNumTOS, 0);
if (thread->isolate()->single_step()) {
Exit(thread, FP, SP + 1, pc);
NativeArguments args(thread, 0, NULL, NULL);
@@ -1788,6 +1862,46 @@ RawObject* Simulator::Call(const Code& code,
}
{
+ BYTECODE(IfEqStrict, A_D);
+ RawObject* lhs = FP[rA];
+ RawObject* rhs = FP[rD];
+ if (lhs != rhs) {
+ pc++;
+ }
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(IfNeStrict, A_D);
+ RawObject* lhs = FP[rA];
+ RawObject* rhs = FP[rD];
+ if (lhs == rhs) {
+ pc++;
+ }
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(IfEqStrictNum, A_D);
+ RawObject* lhs = FP[rA];
+ RawObject* rhs = FP[rD];
+ if (!SimulatorHelpers::IsStrictEqualWithNumberCheck(lhs, rhs)) {
+ pc++;
+ }
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(IfNeStrictNum, A_D);
+ RawObject* lhs = FP[rA];
+ RawObject* rhs = FP[rD];
+ if (SimulatorHelpers::IsStrictEqualWithNumberCheck(lhs, rhs)) {
+ pc++;
+ }
+ DISPATCH();
+ }
+
+ {
BYTECODE(Jump, 0);
const int32_t target = static_cast<int32_t>(op) >> 8;
pc += (target - 1);
@@ -1817,11 +1931,79 @@ RawObject* Simulator::Call(const Code& code,
RawObject* value = SP[3];
ASSERT(array->GetClassId() == kArrayCid);
ASSERT(!index->IsHeapObject());
+ ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
+ array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(StoreIndexed, A_B_C);
+ RawArray* array = static_cast<RawArray*>(FP[rA]);
+ RawSmi* index = static_cast<RawSmi*>(FP[rB]);
+ RawObject* value = FP[rC];
+ ASSERT(array->GetClassId() == kArrayCid);
+ ASSERT(!index->IsHeapObject());
+ ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
DISPATCH();
}
{
+ BYTECODE(Deopt, A_D);
+ const uint16_t deopt_id = rD;
+ if (deopt_id == 0) { // Lazy deoptimization.
+ // Preserve result of the previous call.
+ // TODO(vegorov) we could have actually included result into the
+ // deoptimization environment because it is passed through the stack.
+ // If we do then we could remove special result handling from this code.
+ RawObject* result = SP[0];
+
+ // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
+ // The code in this frame may not cause GC.
+ // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls.
+ EnterSyntheticFrame(&FP, &SP, pc - 1);
+ const intptr_t frame_size_in_bytes =
+ DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP),
+ /*is_lazy_deopt=*/1);
+ LeaveSyntheticFrame(&FP, &SP);
+
+ SP = FP + (frame_size_in_bytes / kWordSize);
+ EnterSyntheticFrame(&FP, &SP, pc - 1);
+ DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP));
+
+ // We are now inside a valid frame.
+ {
+ *++SP = result; // Preserve result (call below can cause GC).
+ *++SP = 0; // Space for the result: number of materialization args.
+ Exit(thread, FP, SP + 1, /*pc=*/0);
+ NativeArguments native_args(thread, 0, SP, SP);
+ INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args);
+ }
+ const intptr_t materialization_arg_count =
+ Smi::Value(RAW_CAST(Smi, *SP--));
+ result = *SP--; // Reload the result. It might have been relocated by GC.
+
+ // Restore caller PC.
+ pc = SavedCallerPC(FP);
+
+ // Check if it is a fake PC marking the entry frame.
+ ASSERT((reinterpret_cast<uword>(pc) & 2) == 0);
+
+ // Restore SP, FP and PP. Push result and dispatch.
+ // Note: unlike in a normal return sequence we don't need to drop
+ // arguments - those are not part of the innermost deoptimization
+ // environment they were dropped by FlowGraphCompiler::RecordAfterCall.
+ SP = FrameArguments(FP, materialization_arg_count);
+ FP = SavedCallerFP(FP);
+ pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
+ *SP = result;
+ } else {
+ UNIMPLEMENTED();
+ }
+ DISPATCH();
+ }
+
+ {
BYTECODE(Trap, 0);
UNIMPLEMENTED();
DISPATCH();
@@ -1847,7 +2029,7 @@ RawObject* Simulator::Call(const Code& code,
RawObject** args = SP - argc;
FP = SavedCallerFP(FP);
if (has_dart_caller) {
- pp = FrameCode(FP)->ptr()->object_pool_->ptr();
+ pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
}
*++SP = null_value;
« no previous file with comments | « runtime/vm/simulator_dbc.h ('k') | runtime/vm/stack_frame.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698