diff options
Diffstat (limited to 'deps/v8/src/x64/lithium-codegen-x64.cc')
-rw-r--r-- | deps/v8/src/x64/lithium-codegen-x64.cc | 154 |
1 files changed, 78 insertions, 76 deletions
diff --git a/deps/v8/src/x64/lithium-codegen-x64.cc b/deps/v8/src/x64/lithium-codegen-x64.cc index f4d75775bb..bfbadebf2d 100644 --- a/deps/v8/src/x64/lithium-codegen-x64.cc +++ b/deps/v8/src/x64/lithium-codegen-x64.cc @@ -9,6 +9,7 @@ #include "src/base/bits.h" #include "src/code-factory.h" #include "src/code-stubs.h" +#include "src/cpu-profiler.h" #include "src/hydrogen-osr.h" #include "src/ic/ic.h" #include "src/ic/stub-cache.h" @@ -128,7 +129,7 @@ bool LCodeGen::GeneratePrologue() { // Sloppy mode functions need to replace the receiver with the global proxy // when called as functions (without an explicit receiver object). - if (info_->this_has_uses() && is_sloppy(info_->language_mode()) && + if (graph()->this_has_uses() && is_sloppy(info_->language_mode()) && !info_->is_native()) { Label ok; StackArgumentsAccessor args(rsp, scope()->num_parameters()); @@ -296,10 +297,10 @@ void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { bool LCodeGen::GenerateJumpTable() { + if (jump_table_.length() == 0) return !is_aborted(); + Label needs_frame; - if (jump_table_.length() > 0) { - Comment(";;; -------------------- Jump table --------------------"); - } + Comment(";;; -------------------- Jump table --------------------"); for (int i = 0; i < jump_table_.length(); i++) { Deoptimizer::JumpTableEntry* table_entry = &jump_table_[i]; __ bind(&table_entry->label); @@ -308,23 +309,7 @@ bool LCodeGen::GenerateJumpTable() { if (table_entry->needs_frame) { DCHECK(!info()->saves_caller_doubles()); __ Move(kScratchRegister, ExternalReference::ForDeoptEntry(entry)); - if (needs_frame.is_bound()) { - __ jmp(&needs_frame); - } else { - __ bind(&needs_frame); - __ movp(rsi, MemOperand(rbp, StandardFrameConstants::kContextOffset)); - __ pushq(rbp); - __ movp(rbp, rsp); - __ Push(rsi); - // This variant of deopt can only be used with stubs. Since we don't - // have a function pointer to install in the stack frame that we're - // building, install a special marker there instead. - DCHECK(info()->IsStub()); - __ Move(rsi, Smi::FromInt(StackFrame::STUB)); - __ Push(rsi); - __ movp(rsi, MemOperand(rsp, kPointerSize)); - __ call(kScratchRegister); - } + __ call(&needs_frame); } else { if (info()->saves_caller_doubles()) { DCHECK(info()->IsStub()); @@ -332,7 +317,58 @@ bool LCodeGen::GenerateJumpTable() { } __ call(entry, RelocInfo::RUNTIME_ENTRY); } + info()->LogDeoptCallPosition(masm()->pc_offset(), + table_entry->deopt_info.inlining_id); + } + + if (needs_frame.is_linked()) { + __ bind(&needs_frame); + /* stack layout + 4: return address <-- rsp + 3: garbage + 2: garbage + 1: garbage + 0: garbage + */ + // Reserve space for context and stub marker. + __ subp(rsp, Immediate(2 * kPointerSize)); + __ Push(MemOperand(rsp, 2 * kPointerSize)); // Copy return address. + __ Push(kScratchRegister); // Save entry address for ret(0) + + /* stack layout + 4: return address + 3: garbage + 2: garbage + 1: return address + 0: entry address <-- rsp + */ + + // Remember context pointer. + __ movp(kScratchRegister, + MemOperand(rbp, StandardFrameConstants::kContextOffset)); + // Save context pointer into the stack frame. + __ movp(MemOperand(rsp, 3 * kPointerSize), kScratchRegister); + + // Create a stack frame. + __ movp(MemOperand(rsp, 4 * kPointerSize), rbp); + __ leap(rbp, MemOperand(rsp, 4 * kPointerSize)); + + // This variant of deopt can only be used with stubs. Since we don't + // have a function pointer to install in the stack frame that we're + // building, install a special marker there instead. + DCHECK(info()->IsStub()); + __ Move(MemOperand(rsp, 2 * kPointerSize), Smi::FromInt(StackFrame::STUB)); + + /* stack layout + 4: old rbp + 3: context pointer + 2: stub marker + 1: return address + 0: entry address <-- rsp + */ + __ ret(0); } + return !is_aborted(); } @@ -768,8 +804,8 @@ void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr, __ bind(&done); } - Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position().raw(), - instr->Mnemonic(), deopt_reason); + Deoptimizer::DeoptInfo deopt_info = MakeDeoptInfo(instr, deopt_reason); + DCHECK(info()->IsStub() || frame_is_built_); // Go through jump table if we need to handle condition, build frame, or // restore caller doubles. @@ -777,6 +813,7 @@ void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr, !info()->saves_caller_doubles()) { DeoptComment(deopt_info); __ call(entry, RelocInfo::RUNTIME_ENTRY); + info()->LogDeoptCallPosition(masm()->pc_offset(), deopt_info.inlining_id); } else { Deoptimizer::JumpTableEntry table_entry(entry, deopt_info, bailout_type, !frame_is_built_); @@ -2614,10 +2651,10 @@ void LCodeGen::EmitClassOfTest(Label* is_true, // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range. // Check if the constructor in the map is a function. - __ movp(temp, FieldOperand(temp, Map::kConstructorOffset)); + __ GetMapConstructor(temp, temp, kScratchRegister); // Objects with a non-function constructor have class 'Object'. - __ CmpObjectType(temp, JS_FUNCTION_TYPE, kScratchRegister); + __ CmpInstanceType(kScratchRegister, JS_FUNCTION_TYPE); if (String::Equals(class_name, isolate()->factory()->Object_string())) { __ j(not_equal, is_true); } else { @@ -2847,16 +2884,6 @@ void LCodeGen::DoReturn(LReturn* instr) { } -void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { - Register result = ToRegister(instr->result()); - __ LoadGlobalCell(result, instr->hydrogen()->cell().handle()); - if (instr->hydrogen()->RequiresHoleCheck()) { - __ CompareRoot(result, Heap::kTheHoleValueRootIndex); - DeoptimizeIf(equal, instr, Deoptimizer::kHole); - } -} - - template <class T> void LCodeGen::EmitVectorLoadICRegisters(T* instr) { DCHECK(FLAG_vector_ics); @@ -2886,37 +2913,12 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); } ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; - Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code(); + Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode, + PREMONOMORPHIC).code(); CallCode(ic, RelocInfo::CODE_TARGET, instr); } -void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { - Register value = ToRegister(instr->value()); - Handle<Cell> cell_handle = instr->hydrogen()->cell().handle(); - - // If the cell we are storing to contains the hole it could have - // been deleted from the property dictionary. In that case, we need - // to update the property details in the property dictionary to mark - // it as no longer deleted. We deoptimize in that case. - if (instr->hydrogen()->RequiresHoleCheck()) { - // We have a temp because CompareRoot might clobber kScratchRegister. - Register cell = ToRegister(instr->temp()); - DCHECK(!value.is(cell)); - __ Move(cell, cell_handle, RelocInfo::CELL); - __ CompareRoot(Operand(cell, 0), Heap::kTheHoleValueRootIndex); - DeoptimizeIf(equal, instr, Deoptimizer::kHole); - // Store the value. - __ movp(Operand(cell, 0), value); - } else { - // Store the value. - __ Move(kScratchRegister, cell_handle, RelocInfo::CELL); - __ movp(Operand(kScratchRegister, 0), value); - } - // Cells are always rescanned, so no write barrier here. -} - - void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { Register context = ToRegister(instr->context()); Register result = ToRegister(instr->result()); @@ -3029,8 +3031,9 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { if (FLAG_vector_ics) { EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); } - Handle<Code> ic = - CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code(); + Handle<Code> ic = CodeFactory::LoadICInOptimizedCode( + isolate(), NOT_CONTEXTUAL, + instr->hydrogen()->initialization_state()).code(); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -3310,7 +3313,9 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr); } - Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code(); + Handle<Code> ic = + CodeFactory::KeyedLoadICInOptimizedCode( + isolate(), instr->hydrogen()->initialization_state()).code(); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -3761,7 +3766,7 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) { __ subq(output_reg, Immediate(1)); DeoptimizeIf(overflow, instr, Deoptimizer::kMinusZero); } - __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); + __ roundsd(xmm_scratch, input_reg, kRoundDown); __ cvttsd2si(output_reg, xmm_scratch); __ cmpl(output_reg, Immediate(0x1)); DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); @@ -3996,14 +4001,8 @@ void LCodeGen::DoMathLog(LMathLog* instr) { void LCodeGen::DoMathClz32(LMathClz32* instr) { Register input = ToRegister(instr->value()); Register result = ToRegister(instr->result()); - Label not_zero_input; - __ bsrl(result, input); - __ j(not_zero, ¬_zero_input); - __ Set(result, 63); // 63^31 == 32 - - __ bind(¬_zero_input); - __ xorl(result, Immediate(31)); // for x in [0..31], 31^x == 31-x. + __ Lzcntl(result, input); } @@ -4270,7 +4269,9 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); __ Move(StoreDescriptor::NameRegister(), instr->hydrogen()->name()); - Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->language_mode()); + Handle<Code> ic = + StoreIC::initialize_stub(isolate(), instr->language_mode(), + instr->hydrogen()->initialization_state()); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -4529,8 +4530,9 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister())); DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); - Handle<Code> ic = - CodeFactory::KeyedStoreIC(isolate(), instr->language_mode()).code(); + Handle<Code> ic = CodeFactory::KeyedStoreICInOptimizedCode( + isolate(), instr->language_mode(), + instr->hydrogen()->initialization_state()).code(); CallCode(ic, RelocInfo::CODE_TARGET, instr); } |