Index: runtime/vm/intermediate_language_x64.cc |
=================================================================== |
--- runtime/vm/intermediate_language_x64.cc (revision 27291) |
+++ runtime/vm/intermediate_language_x64.cc (working copy) |
@@ -96,20 +96,8 @@ |
__ Bind(&done); |
} |
#endif |
- __ LeaveFrame(); |
- __ ret(); |
- // Generate 8 bytes of NOPs so that the debugger can patch the |
- // return pattern with a call to the debug stub. |
- // Note that the nop(8) byte pattern is not recognized by the debugger. |
- __ nop(1); |
- __ nop(1); |
- __ nop(1); |
- __ nop(1); |
- __ nop(1); |
- __ nop(1); |
- __ nop(1); |
- __ nop(1); |
+ __ ReturnPatchable(); |
compiler->AddCurrentDescriptor(PcDescriptors::kReturn, |
Isolate::kNoDeoptId, |
token_pos()); |
@@ -315,7 +303,7 @@ |
// The register allocator drops constant definitions that have no uses. |
if (!locs()->out().IsInvalid()) { |
Register result = locs()->out().reg(); |
- __ LoadObject(result, value()); |
+ __ LoadObject(result, value(), PP); |
} |
} |
@@ -465,12 +453,11 @@ |
const Array& kNoArgumentNames = Object::null_array(); |
const int kNumArgumentsChecked = 2; |
- const Immediate& raw_null = |
- Immediate(reinterpret_cast<intptr_t>(Object::null())); |
Label check_identity; |
- __ cmpq(Address(RSP, 0 * kWordSize), raw_null); |
+ __ LoadObject(TMP, Object::Handle(), PP); |
+ __ cmpq(Address(RSP, 0 * kWordSize), TMP); |
__ j(EQUAL, &check_identity); |
- __ cmpq(Address(RSP, 1 * kWordSize), raw_null); |
+ __ cmpq(Address(RSP, 1 * kWordSize), TMP); |
__ j(EQUAL, &check_identity); |
ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw()); |
@@ -511,10 +498,10 @@ |
__ popq(RDX); |
__ cmpq(RAX, RDX); |
__ j(EQUAL, &is_true); |
- __ LoadObject(RAX, Bool::Get(kind != Token::kEQ)); |
+ __ LoadObject(RAX, Bool::Get(kind != Token::kEQ), PP); |
__ jmp(&equality_done); |
__ Bind(&is_true); |
- __ LoadObject(RAX, Bool::Get(kind == Token::kEQ)); |
+ __ LoadObject(RAX, Bool::Get(kind == Token::kEQ), PP); |
if (kind == Token::kNE) { |
// Skip not-equal result conversion. |
__ jmp(&equality_done); |
@@ -524,7 +511,7 @@ |
// necessary. |
Register ic_data_reg = locs->temp(0).reg(); |
ASSERT(ic_data_reg == RBX); // Stub depends on it. |
- __ LoadObject(ic_data_reg, equality_ic_data); |
+ __ LoadObject(ic_data_reg, equality_ic_data, PP); |
compiler->GenerateCall(token_pos, |
&StubCode::EqualityWithNullArgLabel(), |
PcDescriptors::kRuntimeCall, |
@@ -537,10 +524,10 @@ |
// Negate the condition: true label returns false and vice versa. |
__ CompareObject(RAX, Bool::True()); |
__ j(EQUAL, &true_label, Assembler::kNearJump); |
- __ LoadObject(RAX, Bool::True()); |
+ __ LoadObject(RAX, Bool::True(), PP); |
__ jmp(&done, Assembler::kNearJump); |
__ Bind(&true_label); |
- __ LoadObject(RAX, Bool::False()); |
+ __ LoadObject(RAX, Bool::False(), PP); |
__ Bind(&done); |
} |
__ Bind(&equality_done); |
@@ -610,10 +597,10 @@ |
Register result = locs->out().reg(); |
Label load_true; |
__ j(cond, &load_true, Assembler::kNearJump); |
- __ LoadObject(result, Bool::False()); |
+ __ LoadObject(result, Bool::False(), PP); |
__ jmp(&done); |
__ Bind(&load_true); |
- __ LoadObject(result, Bool::True()); |
+ __ LoadObject(result, Bool::True(), PP); |
} |
} else { |
const int kNumberOfArguments = 2; |
@@ -629,10 +616,10 @@ |
Label false_label; |
__ CompareObject(RAX, Bool::True()); |
__ j(EQUAL, &false_label, Assembler::kNearJump); |
- __ LoadObject(RAX, Bool::True()); |
+ __ LoadObject(RAX, Bool::True(), PP); |
__ jmp(&done); |
__ Bind(&false_label); |
- __ LoadObject(RAX, Bool::False()); |
+ __ LoadObject(RAX, Bool::False(), PP); |
} |
} else { |
if (branch->is_checked()) { |
@@ -666,12 +653,11 @@ |
__ testq(left, Immediate(kSmiTagMask)); |
__ j(ZERO, deopt); |
// 'left' is not Smi. |
- const Immediate& raw_null = |
- Immediate(reinterpret_cast<intptr_t>(Object::null())); |
+ |
Label identity_compare; |
- __ cmpq(right, raw_null); |
+ __ CompareObject(right, Object::Handle()); |
__ j(EQUAL, &identity_compare); |
- __ cmpq(left, raw_null); |
+ __ CompareObject(left, Object::Handle()); |
__ j(EQUAL, &identity_compare); |
__ LoadClassId(temp, left); |
@@ -692,10 +678,10 @@ |
Register result = locs.out().reg(); |
__ j(EQUAL, &is_equal, Assembler::kNearJump); |
// Not equal. |
- __ LoadObject(result, Bool::Get(kind != Token::kEQ)); |
+ __ LoadObject(result, Bool::Get(kind != Token::kEQ), PP); |
__ jmp(&done, Assembler::kNearJump); |
__ Bind(&is_equal); |
- __ LoadObject(result, Bool::Get(kind == Token::kEQ)); |
+ __ LoadObject(result, Bool::Get(kind == Token::kEQ), PP); |
__ Bind(&done); |
} else { |
Condition cond = TokenKindToSmiCondition(kind); |
@@ -718,12 +704,11 @@ |
ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); |
Register left = locs->in(0).reg(); |
Register right = locs->in(1).reg(); |
- const Immediate& raw_null = |
- Immediate(reinterpret_cast<intptr_t>(Object::null())); |
+ |
Label done, identity_compare, non_null_compare; |
- __ cmpq(right, raw_null); |
+ __ CompareObject(right, Object::Handle()); |
__ j(EQUAL, &identity_compare, Assembler::kNearJump); |
- __ cmpq(left, raw_null); |
+ __ CompareObject(left, Object::Handle()); |
__ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); |
// Comparison with NULL is "===". |
__ Bind(&identity_compare); |
@@ -735,10 +720,10 @@ |
Register result = locs->out().reg(); |
Label load_true; |
__ j(cond, &load_true, Assembler::kNearJump); |
- __ LoadObject(result, Bool::False()); |
+ __ LoadObject(result, Bool::False(), PP); |
__ jmp(&done); |
__ Bind(&load_true); |
- __ LoadObject(result, Bool::True()); |
+ __ LoadObject(result, Bool::True(), PP); |
} |
__ jmp(&done); |
__ Bind(&non_null_compare); // Receiver is not null. |
@@ -796,10 +781,10 @@ |
Register result = locs.out().reg(); |
Label done, is_true; |
__ j(true_condition, &is_true); |
- __ LoadObject(result, Bool::False()); |
+ __ LoadObject(result, Bool::False(), PP); |
__ jmp(&done); |
__ Bind(&is_true); |
- __ LoadObject(result, Bool::True()); |
+ __ LoadObject(result, Bool::True(), PP); |
__ Bind(&done); |
} |
} |
@@ -1527,7 +1512,7 @@ |
ASSERT((field_reg != value_reg) && (field_reg != value_cid_reg)); |
} |
- __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); |
+ __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP); |
FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset()); |
FieldAddress field_nullability_operand( |
@@ -1711,7 +1696,7 @@ |
} |
} else { |
if (field_reg != kNoRegister) { |
- __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); |
+ __ LoadObject(field_reg, Field::ZoneHandle(field().raw()), PP); |
} |
if (value_cid == kDynamicCid) { |
@@ -1747,9 +1732,7 @@ |
if (field().is_nullable() && (field_cid != kNullCid)) { |
__ j(EQUAL, &ok); |
- const Immediate& raw_null = |
- Immediate(reinterpret_cast<intptr_t>(Object::null())); |
- __ cmpq(value_reg, raw_null); |
+ __ CompareObject(value_reg, Object::Handle()); |
} |
if (ok_is_fall_through) { |
@@ -1874,7 +1857,7 @@ |
Register value = locs()->in(0).reg(); |
Register temp = locs()->temp(0).reg(); |
- __ LoadObject(temp, field()); |
+ __ LoadObject(temp, field(), PP); |
if (this->value()->NeedsStoreBuffer()) { |
__ StoreIntoObject(temp, |
FieldAddress(temp, Field::value_offset()), value, CanValueBeSmi()); |
@@ -2028,9 +2011,7 @@ |
Label type_arguments_instantiated; |
const intptr_t len = type_arguments().Length(); |
if (type_arguments().IsRawInstantiatedRaw(len)) { |
- const Immediate& raw_null = |
- Immediate(reinterpret_cast<intptr_t>(Object::null())); |
- __ cmpq(instantiator_reg, raw_null); |
+ __ CompareObject(instantiator_reg, Object::Handle()); |
__ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
} |
// Instantiate non-null type arguments. |
@@ -2078,14 +2059,13 @@ |
// the type arguments. |
Label type_arguments_instantiated; |
ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); |
- const Immediate& raw_null = |
- Immediate(reinterpret_cast<intptr_t>(Object::null())); |
- __ cmpq(instantiator_reg, raw_null); |
+ |
+ __ CompareObject(instantiator_reg, Object::Handle()); |
__ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
// Instantiate non-null type arguments. |
// In the non-factory case, we rely on the allocation stub to |
// instantiate the type arguments. |
- __ LoadObject(result_reg, type_arguments()); |
+ __ LoadObject(result_reg, type_arguments(), PP); |
// result_reg: uninstantiated type arguments. |
__ Bind(&type_arguments_instantiated); |
@@ -2120,10 +2100,9 @@ |
// instantiated from null becomes a vector of dynamic, then use null as |
// the type arguments and do not pass the instantiator. |
ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); |
- const Immediate& raw_null = |
- Immediate(reinterpret_cast<intptr_t>(Object::null())); |
+ |
Label instantiator_not_null; |
- __ cmpq(instantiator_reg, raw_null); |
+ __ CompareObject(instantiator_reg, Object::Handle()); |
__ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump); |
// Null was used in VisitExtractConstructorTypeArguments as the |
// instantiated type arguments, no proper instantiator needed. |
@@ -2199,6 +2178,10 @@ |
compiler->assembler()->CodeSize(), |
catch_handler_types_, |
needs_stacktrace()); |
+ |
+ // Restore the pool pointer. |
+ __ LoadPoolPointer(PP); |
+ |
if (HasParallelMove()) { |
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
} |
@@ -2279,7 +2262,7 @@ |
// In unoptimized code check the usage counter to trigger OSR at loop |
// stack checks. Use progressively higher thresholds for more deeply |
// nested loops to attempt to hit outer loops with OSR when possible. |
- __ LoadObject(temp, compiler->parsed_function().function()); |
+ __ LoadObject(temp, compiler->parsed_function().function(), PP); |
intptr_t threshold = |
FLAG_optimization_counter_threshold * (loop_depth() + 1); |
__ cmpq(FieldAddress(temp, Function::usage_counter_offset()), |
@@ -3726,10 +3709,10 @@ |
__ addq(RSP, Immediate(16)); |
__ testl(result, result); |
__ j(NOT_ZERO, &non_zero, Assembler::kNearJump); |
- __ LoadObject(result, Bool::False()); |
+ __ LoadObject(result, Bool::False(), PP); |
__ jmp(&done); |
__ Bind(&non_zero); |
- __ LoadObject(result, Bool::True()); |
+ __ LoadObject(result, Bool::True(), PP); |
__ Bind(&done); |
} |
@@ -4247,9 +4230,9 @@ |
Label check_base_is_one; |
// Check if exponent is 0.0 -> return 1.0; |
- __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0))); |
+ __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(0)), PP); |
__ movsd(zero_temp, FieldAddress(temp, Double::value_offset())); |
- __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1))); |
+ __ LoadObject(temp, Double::ZoneHandle(Double::NewCanonical(1)), PP); |
__ movsd(result, FieldAddress(temp, Double::value_offset())); |
// 'result' contains 1.0. |
__ comisd(exp, zero_temp); |
@@ -4347,9 +4330,8 @@ |
if (IsNullCheck()) { |
Label* deopt = compiler->AddDeoptStub(deopt_id(), |
kDeoptCheckClass); |
- const Immediate& raw_null = |
- Immediate(reinterpret_cast<intptr_t>(Object::null())); |
- __ cmpq(locs()->in(0).reg(), raw_null); |
+ __ CompareObject(locs()->in(0).reg(), |
+ Object::Handle()); |
__ j(EQUAL, deopt); |
return; |
} |
@@ -4559,7 +4541,7 @@ |
counter.SetAt(0, Smi::Handle(Smi::New(0))); |
Label done; |
__ Comment("Edge counter"); |
- __ LoadObject(RAX, counter); |
+ __ LoadObject(RAX, counter, PP); |
__ addq(FieldAddress(RAX, Array::element_offset(0)), |
Immediate(Smi::RawValue(1))); |
__ j(NO_OVERFLOW, &done); |
@@ -4590,7 +4572,7 @@ |
counter.SetAt(0, Smi::Handle(Smi::New(0))); |
Label done; |
__ Comment("Edge counter"); |
- __ LoadObject(RAX, counter); |
+ __ LoadObject(RAX, counter, PP); |
__ addq(FieldAddress(RAX, Array::element_offset(0)), |
Immediate(Smi::RawValue(1))); |
__ j(NO_OVERFLOW, &done); |
@@ -4673,7 +4655,7 @@ |
const bool result = (kind() == Token::kEQ_STRICT) ? |
left.constant().raw() == right.constant().raw() : |
left.constant().raw() != right.constant().raw(); |
- __ LoadObject(locs()->out().reg(), Bool::Get(result)); |
+ __ LoadObject(locs()->out().reg(), Bool::Get(result), PP); |
return; |
} |
if (left.IsConstant()) { |
@@ -4697,10 +4679,10 @@ |
Label load_true, done; |
Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; |
__ j(true_condition, &load_true, Assembler::kNearJump); |
- __ LoadObject(result, Bool::False()); |
+ __ LoadObject(result, Bool::False(), PP); |
__ jmp(&done, Assembler::kNearJump); |
__ Bind(&load_true); |
- __ LoadObject(result, Bool::True()); |
+ __ LoadObject(result, Bool::True(), PP); |
__ Bind(&done); |
} |
@@ -4759,7 +4741,7 @@ |
const Array& arguments_descriptor = |
Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, |
argument_names())); |
- __ LoadObject(temp_reg, arguments_descriptor); |
+ __ LoadObject(temp_reg, arguments_descriptor, PP); |
ASSERT(temp_reg == R10); |
compiler->GenerateDartCall(deopt_id(), |
token_pos(), |
@@ -4782,10 +4764,10 @@ |
Register result = locs()->out().reg(); |
Label done; |
- __ LoadObject(result, Bool::True()); |
+ __ LoadObject(result, Bool::True(), PP); |
__ CompareRegisters(result, value); |
__ j(NOT_EQUAL, &done, Assembler::kNearJump); |
- __ LoadObject(result, Bool::False()); |
+ __ LoadObject(result, Bool::False(), PP); |
__ Bind(&done); |
} |