From 4f114470738c8cc89d55e6bd4af60b0a10e11680 Mon Sep 17 00:00:00 2001 From: "lrn@chromium.org" Date: Thu, 27 Jan 2011 11:58:31 +0000 Subject: [PATCH] X64 Crankshaft: Reapply reverted operations with DoLoadGlobal disabled. Review URL: http://codereview.chromium.org/6397002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6510 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/assembler.h | 3 +- src/x64/deoptimizer-x64.cc | 1 + src/x64/lithium-codegen-x64.cc | 60 +++++++++++++++++++++++++++++++--- src/x64/lithium-x64.cc | 30 ++++++++++------- src/x64/macro-assembler-x64.cc | 16 ++++++--- 5 files changed, 87 insertions(+), 23 deletions(-) diff --git a/src/assembler.h b/src/assembler.h index 4ef61e4b1..a29aa064b 100644 --- a/src/assembler.h +++ b/src/assembler.h @@ -185,7 +185,6 @@ class RelocInfo BASE_EMBEDDED { DEBUG_BREAK, // Code target for the debugger statement. CODE_TARGET, // Code target which is not any of the above. EMBEDDED_OBJECT, - GLOBAL_PROPERTY_CELL, // Everything after runtime_entry (inclusive) is not GC'ed. @@ -203,7 +202,7 @@ class RelocInfo BASE_EMBEDDED { NUMBER_OF_MODES, // must be no greater than 14 - see RelocInfoWriter NONE, // never recorded LAST_CODE_ENUM = CODE_TARGET, - LAST_GCED_ENUM = EMBEDDED_OBJECT + LAST_GCED_ENUM = GLOBAL_PROPERTY_CELL }; diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc index a88cd73eb..60d46ef2b 100644 --- a/src/x64/deoptimizer-x64.cc +++ b/src/x64/deoptimizer-x64.cc @@ -82,6 +82,7 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) { } #ifdef DEBUG // Destroy the code which is not supposed to run again. + CHECK(code->safepoint_table_start() >= last_pc_offset); unsigned instructions = code->safepoint_table_start() - last_pc_offset; CodePatcher destroyer(code->instruction_start() + last_pc_offset, instructions); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index bf0dd5e31..050123b2b 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -188,6 +188,10 @@ bool LCodeGen::GenerateDeferredCode() { bool LCodeGen::GenerateSafepointTable() { ASSERT(is_done()); + // Ensure that patching a deoptimization point won't overwrite the table. + for (int i = 0; i < Assembler::kCallInstructionLength; i++) { + masm()->int3(); + } safepoints_.Emit(masm(), StackSlotCount()); return !is_aborted(); } @@ -1391,7 +1395,18 @@ void LCodeGen::DoReturn(LReturn* instr) { void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { - Abort("Unimplemented: %s", "DoLoadGlobal"); + Register result = ToRegister(instr->result()); + if (result.is(rax)) { + __ load_rax(instr->hydrogen()->cell().location(), + RelocInfo::GLOBAL_PROPERTY_CELL); + } else { + __ movq(result, instr->hydrogen()->cell(), RelocInfo::GLOBAL_PROPERTY_CELL); + __ movq(result, Operand(result, 0)); + } + if (instr->hydrogen()->check_hole_value()) { + __ CompareRoot(result, Heap::kTheHoleValueRootIndex); + DeoptimizeIf(equal, instr->environment()); + } } @@ -1456,7 +1471,26 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { void LCodeGen::DoPushArgument(LPushArgument* instr) { - Abort("Unimplemented: %s", "DoPushArgument"); + LOperand* argument = instr->InputAt(0); + if (argument->IsConstantOperand()) { + LConstantOperand* const_op = LConstantOperand::cast(argument); + Handle literal = chunk_->LookupLiteral(const_op); + Representation r = chunk_->LookupLiteralRepresentation(const_op); + if (r.IsInteger32()) { + ASSERT(literal->IsNumber()); + __ push(Immediate(static_cast(literal->Number()))); + } else if (r.IsDouble()) { + Abort("unsupported double immediate"); + } else { + ASSERT(r.IsTagged()); + __ Push(literal); + } + } else if (argument->IsRegister()) { + __ push(ToRegister(argument)); + } else { + ASSERT(!argument->IsDoubleRegister()); + __ push(ToOperand(argument)); + } } @@ -1564,7 +1598,12 @@ void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { void LCodeGen::DoCallNew(LCallNew* instr) { - Abort("Unimplemented: %s", "DoCallNew"); + ASSERT(ToRegister(instr->InputAt(0)).is(rdi)); + ASSERT(ToRegister(instr->result()).is(rax)); + + Handle builtin(Builtins::builtin(Builtins::JSConstructCall)); + __ Set(rax, instr->arity()); + CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); } @@ -1724,7 +1763,13 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { void LCodeGen::DoCheckSmi(LCheckSmi* instr) { - Abort("Unimplemented: %s", "DoCheckSmi"); + LOperand* input = instr->InputAt(0); + ASSERT(input->IsRegister()); + Condition cc = masm()->CheckSmi(ToRegister(input)); + if (instr->condition() != equal) { + cc = NegateCondition(cc); + } + DeoptimizeIf(cc, instr->environment()); } @@ -1739,7 +1784,12 @@ void LCodeGen::DoCheckFunction(LCheckFunction* instr) { void LCodeGen::DoCheckMap(LCheckMap* instr) { - Abort("Unimplemented: %s", "DoCheckMap"); + LOperand* input = instr->InputAt(0); + ASSERT(input->IsRegister()); + Register reg = ToRegister(input); + __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), + instr->hydrogen()->map()); + DeoptimizeIf(not_equal, instr->environment()); } diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index bdda1fa12..4535fc8eb 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1043,8 +1043,9 @@ LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { - Abort("Unimplemented: %s", "DoPushArgument"); - return NULL; + ++argument_count_; + LOperand* argument = UseOrConstant(instr->argument()); + return new LPushArgument(argument); } @@ -1097,8 +1098,10 @@ LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { - Abort("Unimplemented: %s", "DoCallNew"); - return NULL; + LOperand* constructor = UseFixed(instr->constructor(), rdi); + argument_count_ -= instr->argument_count(); + LCallNew* result = new LCallNew(constructor); + return MarkAsCall(DefineFixed(result, rax), instr); } @@ -1394,8 +1397,8 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { - Abort("Unimplemented: %s", "DoCheckNonSmi"); - return NULL; + LOperand* value = UseRegisterAtStart(instr->value()); + return AssignEnvironment(new LCheckSmi(value, zero)); } @@ -1412,8 +1415,8 @@ LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { - Abort("Unimplemented: %s", "DoCheckSmi"); - return NULL; + LOperand* value = UseRegisterAtStart(instr->value()); + return AssignEnvironment(new LCheckSmi(value, not_zero)); } @@ -1424,8 +1427,9 @@ LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { - Abort("Unimplemented: %s", "DoCheckMap"); - return NULL; + LOperand* value = UseRegisterAtStart(instr->value()); + LCheckMap* result = new LCheckMap(value); + return AssignEnvironment(result); } @@ -1453,8 +1457,10 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { - Abort("Unimplemented: %s", "DoLoadGlobal"); - return NULL; + LLoadGlobal* result = new LLoadGlobal; + return instr->check_hole_value() + ? AssignEnvironment(DefineAsRegister(result)) + : DefineAsRegister(result); } diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index 2fc825fc0..e104e5bb9 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -1770,10 +1770,18 @@ void MacroAssembler::InvokeFunction(JSFunction* function, Move(rdi, Handle(function)); movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); - // Invoke the cached code. - Handle code(function->code()); - ParameterCount expected(function->shared()->formal_parameter_count()); - InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag); + if (V8::UseCrankshaft()) { + // Since Crankshaft can recompile a function, we need to load + // the Code object every time we call the function. + movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); + ParameterCount expected(function->shared()->formal_parameter_count()); + InvokeCode(rdx, expected, actual, flag); + } else { + // Invoke the cached code. + Handle code(function->code()); + ParameterCount expected(function->shared()->formal_parameter_count()); + InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag); + } } -- 2.34.1