| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index 35fdcbb69e46221fcd8c5066723604385be1e2f7..6c8e377d637616d99283fdd027bebd93dd69e1a3 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -143,14 +143,7 @@ bool LCodeGen::GeneratePrologue() {
|
| if (NeedsEagerFrame()) {
|
| ASSERT(!frame_is_built_);
|
| frame_is_built_ = true;
|
| - __ push(rbp); // Caller's frame pointer.
|
| - __ movq(rbp, rsp);
|
| - __ push(rsi); // Callee's context.
|
| - if (info()->IsStub()) {
|
| - __ Push(Smi::FromInt(StackFrame::STUB));
|
| - } else {
|
| - __ push(rdi); // Callee's JS function.
|
| - }
|
| + __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
|
| info()->AddNoFrameRange(0, masm_->pc_offset());
|
| }
|
|
|
| @@ -299,8 +292,9 @@ bool LCodeGen::GenerateDeferredCode() {
|
| for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
|
| LDeferredCode* code = deferred_[i];
|
|
|
| - int pos = instructions_->at(code->instruction_index())->position();
|
| - RecordAndUpdatePosition(pos);
|
| + HValue* value =
|
| + instructions_->at(code->instruction_index())->hydrogen_value();
|
| + RecordAndWritePosition(value->position());
|
|
|
| Comment(";;; <@%d,#%d> "
|
| "-------------------- Deferred %s --------------------",
|
| @@ -563,8 +557,6 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code,
|
| int argc) {
|
| EnsureSpaceForLazyDeopt(Deoptimizer::patch_size() - masm()->CallSize(code));
|
| ASSERT(instr != NULL);
|
| - LPointerMap* pointers = instr->pointer_map();
|
| - RecordPosition(pointers->position());
|
| __ call(code, mode);
|
| RecordSafepointWithLazyDeopt(instr, safepoint_mode, argc);
|
|
|
| @@ -590,8 +582,6 @@ void LCodeGen::CallRuntime(const Runtime::Function* function,
|
| SaveFPRegsMode save_doubles) {
|
| ASSERT(instr != NULL);
|
| ASSERT(instr->HasPointerMap());
|
| - LPointerMap* pointers = instr->pointer_map();
|
| - RecordPosition(pointers->position());
|
|
|
| __ CallRuntime(function, num_arguments, save_doubles);
|
|
|
| @@ -840,7 +830,7 @@ void LCodeGen::RecordSafepoint(LPointerMap* pointers,
|
|
|
|
|
| void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) {
|
| - LPointerMap empty_pointers(RelocInfo::kNoPosition, zone());
|
| + LPointerMap empty_pointers(zone());
|
| RecordSafepoint(&empty_pointers, deopt_mode);
|
| }
|
|
|
| @@ -852,17 +842,10 @@ void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
|
| }
|
|
|
|
|
| -void LCodeGen::RecordPosition(int position) {
|
| +void LCodeGen::RecordAndWritePosition(int position) {
|
| if (position == RelocInfo::kNoPosition) return;
|
| masm()->positions_recorder()->RecordPosition(position);
|
| -}
|
| -
|
| -
|
| -void LCodeGen::RecordAndUpdatePosition(int position) {
|
| - if (position >= 0 && position != old_position_) {
|
| - masm()->positions_recorder()->RecordPosition(position);
|
| - old_position_ = position;
|
| - }
|
| + masm()->positions_recorder()->WriteRecordedPositions();
|
| }
|
|
|
|
|
| @@ -1566,8 +1549,7 @@ void LCodeGen::DoConstantE(LConstantE* instr) {
|
|
|
| void LCodeGen::DoConstantT(LConstantT* instr) {
|
| Handle<Object> value = instr->value(isolate());
|
| - AllowDeferredHandleDereference smi_check;
|
| - __ LoadObject(ToRegister(instr->result()), value);
|
| + __ Move(ToRegister(instr->result()), value);
|
| }
|
|
|
|
|
| @@ -2048,6 +2030,10 @@ inline Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
|
| case Token::EQ_STRICT:
|
| cond = equal;
|
| break;
|
| + case Token::NE:
|
| + case Token::NE_STRICT:
|
| + cond = not_equal;
|
| + break;
|
| case Token::LT:
|
| cond = is_unsigned ? below : less;
|
| break;
|
| @@ -2135,7 +2121,7 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
|
|
|
| if (instr->right()->IsConstantOperand()) {
|
| Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
|
| - __ CmpObject(left, right);
|
| + __ Cmp(left, right);
|
| } else {
|
| Register right = ToRegister(instr->right());
|
| __ cmpq(left, right);
|
| @@ -2503,7 +2489,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
|
| InstanceofStub stub(flags);
|
|
|
| __ push(ToRegister(instr->value()));
|
| - __ PushHeapObject(instr->function());
|
| + __ Push(instr->function());
|
|
|
| static const int kAdditionalDelta = 10;
|
| int delta =
|
| @@ -3172,7 +3158,6 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
|
| __ bind(&invoke);
|
| ASSERT(instr->HasPointerMap());
|
| LPointerMap* pointers = instr->pointer_map();
|
| - RecordPosition(pointers->position());
|
| SafepointGenerator safepoint_generator(
|
| this, pointers, Safepoint::kLazyDeopt);
|
| ParameterCount actual(rax);
|
| @@ -3215,7 +3200,7 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
|
|
|
| void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
|
| __ push(rsi); // The context is the first argument.
|
| - __ PushHeapObject(instr->hydrogen()->pairs());
|
| + __ Push(instr->hydrogen()->pairs());
|
| __ Push(Smi::FromInt(instr->hydrogen()->flags()));
|
| CallRuntime(Runtime::kDeclareGlobals, 3, instr);
|
| }
|
| @@ -3246,11 +3231,10 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
|
| dont_adapt_arguments || formal_parameter_count == arity;
|
|
|
| LPointerMap* pointers = instr->pointer_map();
|
| - RecordPosition(pointers->position());
|
|
|
| if (can_invoke_directly) {
|
| if (rdi_state == RDI_UNINITIALIZED) {
|
| - __ LoadHeapObject(rdi, function);
|
| + __ Move(rdi, function);
|
| }
|
|
|
| // Change context.
|
| @@ -3669,10 +3653,35 @@ void LCodeGen::DoMathExp(LMathExp* instr) {
|
|
|
|
|
| void LCodeGen::DoMathLog(LMathLog* instr) {
|
| - ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
|
| - TranscendentalCacheStub stub(TranscendentalCache::LOG,
|
| - TranscendentalCacheStub::UNTAGGED);
|
| - CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
|
| + ASSERT(instr->value()->Equals(instr->result()));
|
| + XMMRegister input_reg = ToDoubleRegister(instr->value());
|
| + XMMRegister xmm_scratch = double_scratch0();
|
| + Label positive, done, zero;
|
| + __ xorps(xmm_scratch, xmm_scratch);
|
| + __ ucomisd(input_reg, xmm_scratch);
|
| + __ j(above, &positive, Label::kNear);
|
| + __ j(equal, &zero, Label::kNear);
|
| + ExternalReference nan =
|
| + ExternalReference::address_of_canonical_non_hole_nan();
|
| + Operand nan_operand = masm()->ExternalOperand(nan);
|
| + __ movsd(input_reg, nan_operand);
|
| + __ jmp(&done, Label::kNear);
|
| + __ bind(&zero);
|
| + ExternalReference ninf =
|
| + ExternalReference::address_of_negative_infinity();
|
| + Operand ninf_operand = masm()->ExternalOperand(ninf);
|
| + __ movsd(input_reg, ninf_operand);
|
| + __ jmp(&done, Label::kNear);
|
| + __ bind(&positive);
|
| + __ fldln2();
|
| + __ subq(rsp, Immediate(kDoubleSize));
|
| + __ movsd(Operand(rsp, 0), input_reg);
|
| + __ fld_d(Operand(rsp, 0));
|
| + __ fyl2x();
|
| + __ fstp_d(Operand(rsp, 0));
|
| + __ movsd(input_reg, Operand(rsp, 0));
|
| + __ addq(rsp, Immediate(kDoubleSize));
|
| + __ bind(&done);
|
| }
|
|
|
|
|
| @@ -3707,7 +3716,6 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
|
| Handle<JSFunction> known_function = instr->hydrogen()->known_function();
|
| if (known_function.is_null()) {
|
| LPointerMap* pointers = instr->pointer_map();
|
| - RecordPosition(pointers->position());
|
| SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
|
| ParameterCount count(instr->arity());
|
| __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
|
| @@ -4257,8 +4265,10 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
|
| void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
|
| Register object = ToRegister(instr->object());
|
| Register temp = ToRegister(instr->temp());
|
| - __ TestJSArrayForAllocationMemento(object, temp);
|
| + Label no_memento_found;
|
| + __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
|
| DeoptimizeIf(equal, instr->environment());
|
| + __ bind(&no_memento_found);
|
| }
|
|
|
|
|
| @@ -4612,24 +4622,38 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
|
|
|
|
|
| void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) {
|
| - Label heap_number;
|
| Register input_reg = ToRegister(instr->value());
|
|
|
| -
|
| if (instr->truncating()) {
|
| + Label no_heap_number, check_bools, check_false;
|
| +
|
| // Heap number map check.
|
| __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
|
| Heap::kHeapNumberMapRootIndex);
|
| - __ j(equal, &heap_number, Label::kNear);
|
| - // Check for undefined. Undefined is converted to zero for truncating
|
| - // conversions.
|
| + __ j(not_equal, &no_heap_number, Label::kNear);
|
| + __ TruncateHeapNumberToI(input_reg, input_reg);
|
| + __ jmp(done);
|
| +
|
| + __ bind(&no_heap_number);
|
| + // Check for Oddballs. Undefined/False is converted to zero and True to one
|
| + // for truncating conversions.
|
| __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
|
| - DeoptimizeIf(not_equal, instr->environment());
|
| + __ j(not_equal, &check_bools, Label::kNear);
|
| __ Set(input_reg, 0);
|
| __ jmp(done);
|
|
|
| - __ bind(&heap_number);
|
| - __ TruncateHeapNumberToI(input_reg, input_reg);
|
| + __ bind(&check_bools);
|
| + __ CompareRoot(input_reg, Heap::kTrueValueRootIndex);
|
| + __ j(not_equal, &check_false, Label::kNear);
|
| + __ Set(input_reg, 1);
|
| + __ jmp(done);
|
| +
|
| + __ bind(&check_false);
|
| + __ CompareRoot(input_reg, Heap::kFalseValueRootIndex);
|
| + __ RecordComment("Deferred TaggedToI: cannot truncate");
|
| + DeoptimizeIf(not_equal, instr->environment());
|
| + __ Set(input_reg, 0);
|
| + __ jmp(done);
|
| } else {
|
| Label bailout;
|
| XMMRegister xmm_temp = ToDoubleRegister(instr->temp());
|
| @@ -4806,8 +4830,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
|
|
|
| void LCodeGen::DoCheckValue(LCheckValue* instr) {
|
| Register reg = ToRegister(instr->value());
|
| - Handle<HeapObject> object = instr->hydrogen()->object().handle();
|
| - __ CmpHeapObject(reg, object);
|
| + __ Cmp(reg, instr->hydrogen()->object().handle());
|
| DeoptimizeIf(not_equal, instr->environment());
|
| }
|
|
|
| @@ -5034,7 +5057,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
|
| // rax = regexp literal clone.
|
| int literal_offset =
|
| FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
|
| - __ LoadHeapObject(rcx, instr->hydrogen()->literals());
|
| + __ Move(rcx, instr->hydrogen()->literals());
|
| __ movq(rbx, FieldOperand(rcx, literal_offset));
|
| __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
|
| __ j(not_equal, &materialized, Label::kNear);
|
| @@ -5105,13 +5128,7 @@ void LCodeGen::DoTypeof(LTypeof* instr) {
|
| void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
|
| ASSERT(!operand->IsDoubleRegister());
|
| if (operand->IsConstantOperand()) {
|
| - Handle<Object> object = ToHandle(LConstantOperand::cast(operand));
|
| - AllowDeferredHandleDereference smi_check;
|
| - if (object->IsSmi()) {
|
| - __ Push(Handle<Smi>::cast(object));
|
| - } else {
|
| - __ PushHeapObject(Handle<HeapObject>::cast(object));
|
| - }
|
| + __ Push(ToHandle(LConstantOperand::cast(operand)));
|
| } else if (operand->IsRegister()) {
|
| __ push(ToRegister(operand));
|
| } else {
|
| @@ -5225,7 +5242,7 @@ void LCodeGen::EmitIsConstructCall(Register temp) {
|
| __ Cmp(Operand(temp, StandardFrameConstants::kContextOffset),
|
| Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
| __ j(not_equal, &check_frame_marker, Label::kNear);
|
| - __ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset));
|
| + __ movq(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
|
|
|
| // Check the marker in the calling frame.
|
| __ bind(&check_frame_marker);
|
|
|