summaryrefslogtreecommitdiff
path: root/deps/v8/src/x64/lithium-codegen-x64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/x64/lithium-codegen-x64.cc')
-rw-r--r--deps/v8/src/x64/lithium-codegen-x64.cc154
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, &not_zero_input);
- __ Set(result, 63); // 63^31 == 32
-
- __ bind(&not_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);
}