Index: runtime/vm/flow_graph_compiler_x64.cc |
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc |
index b75a1ae17cf285f62abe2545dae0721d51dab88b..5c97ebc35cd47c19082c477200441f0eef8cbcd3 100644 |
--- a/runtime/vm/flow_graph_compiler_x64.cc |
+++ b/runtime/vm/flow_graph_compiler_x64.cc |
@@ -26,7 +26,6 @@ DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization."); |
DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic."); |
DECLARE_FLAG(bool, enable_simd_inline); |
- |
FlowGraphCompiler::~FlowGraphCompiler() { |
// BlockInfos are zone-allocated, so their destructors are not called. |
// Verify the labels explicitly here. |
@@ -36,45 +35,37 @@ FlowGraphCompiler::~FlowGraphCompiler() { |
} |
} |
- |
bool FlowGraphCompiler::SupportsUnboxedDoubles() { |
return true; |
} |
- |
bool FlowGraphCompiler::SupportsUnboxedMints() { |
return FLAG_unbox_mints; |
} |
- |
bool FlowGraphCompiler::SupportsUnboxedSimd128() { |
return FLAG_enable_simd_inline; |
} |
- |
bool FlowGraphCompiler::SupportsHardwareDivision() { |
return true; |
} |
- |
bool FlowGraphCompiler::CanConvertUnboxedMintToDouble() { |
return false; |
} |
- |
void FlowGraphCompiler::EnterIntrinsicMode() { |
ASSERT(!intrinsic_mode()); |
intrinsic_mode_ = true; |
ASSERT(!assembler()->constant_pool_allowed()); |
} |
- |
void FlowGraphCompiler::ExitIntrinsicMode() { |
ASSERT(intrinsic_mode()); |
intrinsic_mode_ = false; |
} |
- |
RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, |
DeoptInfoBuilder* builder, |
const Array& deopt_table) { |
@@ -161,7 +152,6 @@ RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, |
return builder->CreateDeoptInfo(deopt_table); |
} |
- |
void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, |
intptr_t stub_ix) { |
// Calls do not need stubs, they share a deoptimization trampoline. |
@@ -183,10 +173,8 @@ void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, |
#undef __ |
} |
- |
#define __ assembler()-> |
- |
// Fall through if bool_register contains null. |
void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, |
Label* is_true, |
@@ -200,7 +188,6 @@ void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, |
__ Bind(&fall_through); |
} |
- |
// Clobbers RCX. |
RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( |
TypeTestStubKind test_kind, |
@@ -244,7 +231,6 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateCallSubtypeTestStub( |
return type_test_cache.raw(); |
} |
- |
// Jumps to labels 'is_instance' or 'is_not_instance' respectively, if |
// type test is conclusive, otherwise fallthrough if a type test could not |
// be completed. |
@@ -322,7 +308,6 @@ FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest( |
is_instance_lbl, is_not_instance_lbl); |
} |
- |
void FlowGraphCompiler::CheckClassIds(Register class_id_reg, |
const GrowableArray<intptr_t>& class_ids, |
Label* is_equal_lbl, |
@@ -334,7 +319,6 @@ void FlowGraphCompiler::CheckClassIds(Register class_id_reg, |
__ jmp(is_not_equal_lbl); |
} |
- |
// Testing against an instantiated type with no arguments, without |
// SubtypeTestCache. |
// RAX: instance to test against (preserved). |
@@ -402,7 +386,6 @@ bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest( |
return true; |
} |
- |
// Uses SubtypeTestCache to store instance class and result. |
// RAX: instance to test. |
// Clobbers R10, R13. |
@@ -434,7 +417,6 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup( |
is_instance_lbl, is_not_instance_lbl); |
} |
- |
// Generates inlined check if 'type' is a type parameter or type itself |
// RAX: instance (preserved). |
// Clobbers RDI, RDX, R10. |
@@ -515,7 +497,6 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest( |
return SubtypeTestCache::null(); |
} |
- |
// Inputs: |
// - RAX: instance to test against (preserved). |
// - RDX: optional instantiator type arguments (preserved). |
@@ -558,7 +539,6 @@ RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof( |
is_not_instance_lbl); |
} |
- |
// If instanceof type test cannot be performed successfully at compile time and |
// therefore eliminated, optimize it by adding inlined tests for: |
// - NULL -> return type == Null (type is not Object or dynamic). |
@@ -606,11 +586,11 @@ void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos, |
// Generate runtime call. |
__ movq(RDX, Address(RSP, 1 * kWordSize)); // Get instantiator type args. |
__ movq(RCX, Address(RSP, 0 * kWordSize)); // Get function type args. |
- __ PushObject(Object::null_object()); // Make room for the result. |
- __ pushq(RAX); // Push the instance. |
- __ PushObject(type); // Push the type. |
- __ pushq(RDX); // Instantiator type arguments. |
- __ pushq(RCX); // Function type arguments. |
+ __ PushObject(Object::null_object()); // Make room for the result. |
+ __ pushq(RAX); // Push the instance. |
+ __ PushObject(type); // Push the type. |
+ __ pushq(RDX); // Instantiator type arguments. |
+ __ pushq(RCX); // Function type arguments. |
__ LoadUniqueObject(RAX, test_cache); |
__ pushq(RAX); |
GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs); |
@@ -631,7 +611,6 @@ void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos, |
__ popq(RDX); // Remove pushed instantiator type arguments. |
} |
- |
// Optimize assignable type check by adding inlined tests for: |
// - NULL -> return NULL. |
// - Smi -> compile time subtype check (only if dst class is not parameterized). |
@@ -688,12 +667,12 @@ void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos, |
__ Bind(&runtime_call); |
__ movq(RDX, Address(RSP, 1 * kWordSize)); // Get instantiator type args. |
__ movq(RCX, Address(RSP, 0 * kWordSize)); // Get function type args. |
- __ PushObject(Object::null_object()); // Make room for the result. |
- __ pushq(RAX); // Push the source object. |
- __ PushObject(dst_type); // Push the type of the destination. |
- __ pushq(RDX); // Instantiator type arguments. |
- __ pushq(RCX); // Function type arguments. |
- __ PushObject(dst_name); // Push the name of the destination. |
+ __ PushObject(Object::null_object()); // Make room for the result. |
+ __ pushq(RAX); // Push the source object. |
+ __ PushObject(dst_type); // Push the type of the destination. |
+ __ pushq(RDX); // Instantiator type arguments. |
+ __ pushq(RCX); // Function type arguments. |
+ __ PushObject(dst_name); // Push the name of the destination. |
__ LoadUniqueObject(RAX, test_cache); |
__ pushq(RAX); |
GenerateRuntimeCall(token_pos, deopt_id, kTypeCheckRuntimeEntry, 6, locs); |
@@ -707,7 +686,6 @@ void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos, |
__ popq(RDX); // Remove pushed instantiator type arguments. |
} |
- |
void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { |
if (is_optimizing()) { |
return; |
@@ -726,7 +704,6 @@ void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { |
} |
} |
- |
void FlowGraphCompiler::CopyParameters() { |
__ Comment("Copy parameters"); |
const Function& function = parsed_function().function(); |
@@ -929,7 +906,6 @@ void FlowGraphCompiler::CopyParameters() { |
__ j(POSITIVE, &null_args_loop, Assembler::kNearJump); |
} |
- |
void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { |
// TOS: return address. |
// +1 : receiver. |
@@ -940,7 +916,6 @@ void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { |
__ ret(); |
} |
- |
void FlowGraphCompiler::GenerateInlinedSetter(intptr_t offset) { |
// TOS: return address. |
// +1 : value |
@@ -954,7 +929,6 @@ void FlowGraphCompiler::GenerateInlinedSetter(intptr_t offset) { |
__ ret(); |
} |
- |
// NOTE: If the entry code shape changes, ReturnAddressLocator in profiler.cc |
// needs to be updated to match. |
void FlowGraphCompiler::EmitFrameEntry() { |
@@ -991,7 +965,6 @@ void FlowGraphCompiler::EmitFrameEntry() { |
} |
} |
- |
void FlowGraphCompiler::CompileGraph() { |
InitCompiler(); |
const Function& function = parsed_function().function(); |
@@ -1127,7 +1100,6 @@ void FlowGraphCompiler::CompileGraph() { |
GenerateDeferredCode(); |
} |
- |
void FlowGraphCompiler::GenerateCall(TokenPosition token_pos, |
const StubEntry& stub_entry, |
RawPcDescriptors::Kind kind, |
@@ -1136,7 +1108,6 @@ void FlowGraphCompiler::GenerateCall(TokenPosition token_pos, |
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs); |
} |
- |
void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos, |
const StubEntry& stub_entry, |
RawPcDescriptors::Kind kind, |
@@ -1145,7 +1116,6 @@ void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos, |
EmitCallsiteMetaData(token_pos, Thread::kNoDeoptId, kind, locs); |
} |
- |
void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, |
TokenPosition token_pos, |
const StubEntry& stub_entry, |
@@ -1165,7 +1135,6 @@ void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, |
} |
} |
- |
void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id, |
TokenPosition token_pos, |
const StubEntry& stub_entry, |
@@ -1192,7 +1161,6 @@ void FlowGraphCompiler::GenerateStaticDartCall(intptr_t deopt_id, |
AddStaticCallTarget(target); |
} |
- |
void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos, |
intptr_t deopt_id, |
const RuntimeEntry& entry, |
@@ -1214,7 +1182,6 @@ void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos, |
} |
} |
- |
void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t argument_count, |
intptr_t deopt_id, |
TokenPosition token_pos, |
@@ -1228,7 +1195,6 @@ void FlowGraphCompiler::EmitUnoptimizedStaticCall(intptr_t argument_count, |
__ Drop(argument_count, RCX); |
} |
- |
void FlowGraphCompiler::EmitEdgeCounter(intptr_t edge_id) { |
// We do not check for overflow when incrementing the edge counter. The |
// function should normally be optimized long before the counter can |
@@ -1242,7 +1208,6 @@ void FlowGraphCompiler::EmitEdgeCounter(intptr_t edge_id) { |
__ IncrementSmiField(FieldAddress(RAX, Array::element_offset(edge_id)), 1); |
} |
- |
void FlowGraphCompiler::EmitOptimizedInstanceCall(const StubEntry& stub_entry, |
const ICData& ic_data, |
intptr_t argument_count, |
@@ -1263,7 +1228,6 @@ void FlowGraphCompiler::EmitOptimizedInstanceCall(const StubEntry& stub_entry, |
__ Drop(argument_count, RCX); |
} |
- |
void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry, |
const ICData& ic_data, |
intptr_t argument_count, |
@@ -1277,7 +1241,6 @@ void FlowGraphCompiler::EmitInstanceCall(const StubEntry& stub_entry, |
__ Drop(argument_count, RCX); |
} |
- |
void FlowGraphCompiler::EmitMegamorphicInstanceCall( |
const String& name, |
const Array& arguments_descriptor, |
@@ -1322,7 +1285,6 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall( |
__ Drop(argument_count, RCX); |
} |
- |
void FlowGraphCompiler::EmitSwitchableInstanceCall(const ICData& ic_data, |
intptr_t argument_count, |
intptr_t deopt_id, |
@@ -1339,7 +1301,6 @@ void FlowGraphCompiler::EmitSwitchableInstanceCall(const ICData& ic_data, |
__ LoadUniqueObject(RBX, ic_data); |
__ call(RCX); |
- |
EmitCallsiteMetaData(token_pos, deopt_id, RawPcDescriptors::kOther, locs); |
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id); |
if (is_optimizing()) { |
@@ -1352,7 +1313,6 @@ void FlowGraphCompiler::EmitSwitchableInstanceCall(const ICData& ic_data, |
__ Drop(argument_count, RCX); |
} |
- |
void FlowGraphCompiler::EmitOptimizedStaticCall( |
const Function& function, |
const Array& arguments_descriptor, |
@@ -1375,7 +1335,6 @@ void FlowGraphCompiler::EmitOptimizedStaticCall( |
__ Drop(argument_count, RCX); |
} |
- |
Condition FlowGraphCompiler::EmitEqualityRegConstCompare( |
Register reg, |
const Object& obj, |
@@ -1409,7 +1368,6 @@ Condition FlowGraphCompiler::EmitEqualityRegConstCompare( |
return EQUAL; |
} |
- |
Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, |
Register right, |
bool needs_number_check, |
@@ -1433,7 +1391,6 @@ Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left, |
return EQUAL; |
} |
- |
// This function must be in sync with FlowGraphCompiler::RecordSafepoint and |
// FlowGraphCompiler::SlowPathEnvironmentFor. |
void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { |
@@ -1447,13 +1404,11 @@ void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { |
locs->live_registers()->fpu_registers()); |
} |
- |
void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) { |
__ PopRegisters(locs->live_registers()->cpu_registers(), |
locs->live_registers()->fpu_registers()); |
} |
- |
#if defined(DEBUG) |
void FlowGraphCompiler::ClobberDeadTempRegisters(LocationSummary* locs) { |
// Clobber temporaries that have not been manually preserved. |
@@ -1468,7 +1423,6 @@ void FlowGraphCompiler::ClobberDeadTempRegisters(LocationSummary* locs) { |
} |
#endif |
- |
void FlowGraphCompiler::EmitTestAndCallLoadReceiver( |
intptr_t argument_count, |
const Array& arguments_descriptor) { |
@@ -1478,19 +1432,16 @@ void FlowGraphCompiler::EmitTestAndCallLoadReceiver( |
__ LoadObject(R10, arguments_descriptor); |
} |
- |
void FlowGraphCompiler::EmitTestAndCallSmiBranch(Label* label, bool if_smi) { |
__ testq(RAX, Immediate(kSmiTagMask)); |
// Jump if receiver is (not) Smi. |
__ j(if_smi ? ZERO : NOT_ZERO, label); |
} |
- |
void FlowGraphCompiler::EmitTestAndCallLoadCid() { |
__ LoadClassId(RDI, RAX); |
} |
- |
int FlowGraphCompiler::EmitTestAndCallCheckCid(Label* next_label, |
const CidRange& range, |
int bias) { |
@@ -1507,11 +1458,9 @@ int FlowGraphCompiler::EmitTestAndCallCheckCid(Label* next_label, |
return bias; |
} |
- |
#undef __ |
#define __ compiler_->assembler()-> |
- |
void ParallelMoveResolver::EmitMove(int index) { |
MoveOperands* move = moves_[index]; |
const Location source = move->src(); |
@@ -1605,7 +1554,6 @@ void ParallelMoveResolver::EmitMove(int index) { |
move->Eliminate(); |
} |
- |
void ParallelMoveResolver::EmitSwap(int index) { |
MoveOperands* move = moves_[index]; |
const Location source = move->src(); |
@@ -1681,35 +1629,29 @@ void ParallelMoveResolver::EmitSwap(int index) { |
} |
} |
- |
void ParallelMoveResolver::MoveMemoryToMemory(const Address& dst, |
const Address& src) { |
__ MoveMemoryToMemory(dst, src); |
} |
- |
void ParallelMoveResolver::StoreObject(const Address& dst, const Object& obj) { |
__ StoreObject(dst, obj); |
} |
- |
void ParallelMoveResolver::Exchange(Register reg, const Address& mem) { |
__ Exchange(reg, mem); |
} |
- |
void ParallelMoveResolver::Exchange(const Address& mem1, const Address& mem2) { |
__ Exchange(mem1, mem2); |
} |
- |
void ParallelMoveResolver::Exchange(Register reg, |
Register base_reg, |
intptr_t stack_offset) { |
UNREACHABLE(); |
} |
- |
void ParallelMoveResolver::Exchange(Register base_reg1, |
intptr_t stack_offset1, |
Register base_reg2, |
@@ -1717,29 +1659,24 @@ void ParallelMoveResolver::Exchange(Register base_reg1, |
UNREACHABLE(); |
} |
- |
void ParallelMoveResolver::SpillScratch(Register reg) { |
__ pushq(reg); |
} |
- |
void ParallelMoveResolver::RestoreScratch(Register reg) { |
__ popq(reg); |
} |
- |
void ParallelMoveResolver::SpillFpuScratch(FpuRegister reg) { |
__ AddImmediate(RSP, Immediate(-kFpuRegisterSize)); |
__ movups(Address(RSP, 0), reg); |
} |
- |
void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { |
__ movups(reg, Address(RSP, 0)); |
__ AddImmediate(RSP, Immediate(kFpuRegisterSize)); |
} |
- |
#undef __ |
} // namespace dart |