Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/src/crankshaft/x64/lithium-codegen-x64.cc b/src/crankshaft/x64/lithium-codegen-x64.cc
index fbda59b..350543e 100644
--- a/src/crankshaft/x64/lithium-codegen-x64.cc
+++ b/src/crankshaft/x64/lithium-codegen-x64.cc
@@ -168,11 +168,11 @@
Comment(";;; Prologue begin");
// Possibly allocate a local context.
- if (info_->num_heap_slots() > 0) {
+ if (info_->scope()->num_heap_slots() > 0) {
Comment(";;; Allocate local context");
bool need_write_barrier = true;
// Argument to NewContext is the function, which is still in rdi.
- int slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+ int slots = info_->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
Safepoint::DeoptMode deopt_mode = Safepoint::kNoLazyDeopt;
if (info()->scope()->is_script_scope()) {
__ Push(rdi);
@@ -299,8 +299,6 @@
}
__ call(entry, RelocInfo::RUNTIME_ENTRY);
}
- info()->LogDeoptCallPosition(masm()->pc_offset(),
- table_entry->deopt_info.inlining_id);
}
if (needs_frame.is_linked()) {
@@ -748,7 +746,7 @@
__ bind(&done);
}
- Deoptimizer::DeoptInfo deopt_info = MakeDeoptInfo(instr, deopt_reason);
+ Deoptimizer::DeoptInfo deopt_info = MakeDeoptInfo(instr, deopt_reason, id);
DCHECK(info()->IsStub() || frame_is_built_);
// Go through jump table if we need to handle condition, build frame, or
@@ -757,7 +755,6 @@
!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_);
@@ -2441,16 +2438,6 @@
}
-void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
- DCHECK(ToRegister(instr->context()).is(rsi));
- DCHECK(ToRegister(instr->left()).is(InstanceOfDescriptor::LeftRegister()));
- DCHECK(ToRegister(instr->right()).is(InstanceOfDescriptor::RightRegister()));
- DCHECK(ToRegister(instr->result()).is(rax));
- InstanceOfStub stub(isolate());
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoHasInPrototypeChainAndBranch(
LHasInPrototypeChainAndBranch* instr) {
Register const object = ToRegister(instr->object());
@@ -3287,8 +3274,19 @@
DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber);
Label slow, allocated, done;
- Register tmp = input_reg.is(rax) ? rcx : rax;
- Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx;
+ uint32_t available_regs = rax.bit() | rcx.bit() | rdx.bit() | rbx.bit();
+ available_regs &= ~input_reg.bit();
+ if (instr->context()->IsRegister()) {
+ // Make sure that the context isn't overwritten in the AllocateHeapNumber
+ // macro below.
+ available_regs &= ~ToRegister(instr->context()).bit();
+ }
+
+ Register tmp =
+ Register::from_code(base::bits::CountTrailingZeros32(available_regs));
+ available_regs &= ~tmp.bit();
+ Register tmp2 =
+ Register::from_code(base::bits::CountTrailingZeros32(available_regs));
// Preserve the value of all registers.
PushSafepointRegistersScope scope(this);
@@ -5162,7 +5160,7 @@
Register temp = ToRegister(instr->temp());
// Allocate memory for the object.
- AllocationFlags flags = TAG_OBJECT;
+ AllocationFlags flags = NO_ALLOCATION_FLAGS;
if (instr->hydrogen()->MustAllocateDoubleAligned()) {
flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT);
}
@@ -5171,6 +5169,11 @@
flags = static_cast<AllocationFlags>(flags | PRETENURE);
}
+ if (instr->hydrogen()->IsAllocationFoldingDominator()) {
+ flags = static_cast<AllocationFlags>(flags | ALLOCATION_FOLDING_DOMINATOR);
+ }
+ DCHECK(!instr->hydrogen()->IsAllocationFolded());
+
if (instr->size()->IsConstantOperand()) {
int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
CHECK(size <= Page::kMaxRegularHeapObjectSize);
@@ -5200,6 +5203,29 @@
}
}
+void LCodeGen::DoFastAllocate(LFastAllocate* instr) {
+ DCHECK(instr->hydrogen()->IsAllocationFolded());
+ DCHECK(!instr->hydrogen()->IsAllocationFoldingDominator());
+ Register result = ToRegister(instr->result());
+ Register temp = ToRegister(instr->temp());
+
+ AllocationFlags flags = ALLOCATION_FOLDED;
+ if (instr->hydrogen()->MustAllocateDoubleAligned()) {
+ flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT);
+ }
+ if (instr->hydrogen()->IsOldSpaceAllocation()) {
+ DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
+ flags = static_cast<AllocationFlags>(flags | PRETENURE);
+ }
+ if (instr->size()->IsConstantOperand()) {
+ int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
+ CHECK(size <= Page::kMaxRegularHeapObjectSize);
+ __ FastAllocate(size, result, temp, flags);
+ } else {
+ Register size = ToRegister(instr->size());
+ __ FastAllocate(size, result, temp, flags);
+ }
+}
void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
Register result = ToRegister(instr->result());
@@ -5232,6 +5258,22 @@
CallRuntimeFromDeferred(
Runtime::kAllocateInTargetSpace, 2, instr, instr->context());
__ StoreToSafepointRegisterSlot(result, rax);
+
+ if (instr->hydrogen()->IsAllocationFoldingDominator()) {
+ AllocationFlags allocation_flags = NO_ALLOCATION_FLAGS;
+ if (instr->hydrogen()->IsOldSpaceAllocation()) {
+ DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
+ allocation_flags = static_cast<AllocationFlags>(flags | PRETENURE);
+ }
+ // If the allocation folding dominator allocate triggered a GC, allocation
+ // happend in the runtime. We have to reset the top pointer to virtually
+ // undo the allocation.
+ ExternalReference allocation_top =
+ AllocationUtils::GetAllocationTopReference(isolate(), allocation_flags);
+ __ subp(rax, Immediate(kHeapObjectTag));
+ __ Store(allocation_top, rax);
+ __ addp(rax, Immediate(kHeapObjectTag));
+ }
}
diff --git a/src/crankshaft/x64/lithium-codegen-x64.h b/src/crankshaft/x64/lithium-codegen-x64.h
index 139645e..f643e2b 100644
--- a/src/crankshaft/x64/lithium-codegen-x64.h
+++ b/src/crankshaft/x64/lithium-codegen-x64.h
@@ -111,8 +111,6 @@
#undef DECLARE_DO
private:
- LanguageMode language_mode() const { return info()->language_mode(); }
-
LPlatformChunk* chunk() const { return chunk_; }
Scope* scope() const { return scope_; }
HGraph* graph() const { return chunk()->graph(); }
diff --git a/src/crankshaft/x64/lithium-x64.cc b/src/crankshaft/x64/lithium-x64.cc
index e86b90c..daedd72 100644
--- a/src/crankshaft/x64/lithium-x64.cc
+++ b/src/crankshaft/x64/lithium-x64.cc
@@ -907,7 +907,7 @@
LInstruction* LChunkBuilder::DoPrologue(HPrologue* instr) {
LInstruction* result = new (zone()) LPrologue();
- if (info_->num_heap_slots() > 0) {
+ if (info_->scope()->num_heap_slots() > 0) {
result = MarkAsCall(result, instr);
}
return result;
@@ -957,17 +957,6 @@
}
-LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
- LOperand* left =
- UseFixed(instr->left(), InstanceOfDescriptor::LeftRegister());
- LOperand* right =
- UseFixed(instr->right(), InstanceOfDescriptor::RightRegister());
- LOperand* context = UseFixed(instr->context(), rsi);
- LInstanceOf* result = new (zone()) LInstanceOf(context, left, right);
- return MarkAsCall(DefineFixed(result, rax), instr);
-}
-
-
LInstruction* LChunkBuilder::DoHasInPrototypeChainAndBranch(
HHasInPrototypeChainAndBranch* instr) {
LOperand* object = UseRegister(instr->object());
@@ -2408,14 +2397,19 @@
LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
- info()->MarkAsDeferredCalling();
- LOperand* context = UseAny(instr->context());
- LOperand* size = instr->size()->IsConstant()
- ? UseConstant(instr->size())
- : UseTempRegister(instr->size());
- LOperand* temp = TempRegister();
- LAllocate* result = new(zone()) LAllocate(context, size, temp);
- return AssignPointerMap(DefineAsRegister(result));
+ LOperand* size = instr->size()->IsConstant() ? UseConstant(instr->size())
+ : UseRegister(instr->size());
+ if (instr->IsAllocationFolded()) {
+ LOperand* temp = TempRegister();
+ LFastAllocate* result = new (zone()) LFastAllocate(size, temp);
+ return DefineAsRegister(result);
+ } else {
+ info()->MarkAsDeferredCalling();
+ LOperand* context = UseAny(instr->context());
+ LOperand* temp = TempRegister();
+ LAllocate* result = new (zone()) LAllocate(context, size, temp);
+ return AssignPointerMap(DefineAsRegister(result));
+ }
}
diff --git a/src/crankshaft/x64/lithium-x64.h b/src/crankshaft/x64/lithium-x64.h
index 1feba4b..91f5541 100644
--- a/src/crankshaft/x64/lithium-x64.h
+++ b/src/crankshaft/x64/lithium-x64.h
@@ -67,6 +67,7 @@
V(Drop) \
V(DummyUse) \
V(Dummy) \
+ V(FastAllocate) \
V(FlooringDivByConstI) \
V(FlooringDivByPowerOf2I) \
V(FlooringDivI) \
@@ -78,7 +79,6 @@
V(HasInPrototypeChainAndBranch) \
V(HasInstanceTypeAndBranch) \
V(InnerAllocatedObject) \
- V(InstanceOf) \
V(InstructionGap) \
V(Integer32ToDouble) \
V(InvokeFunction) \
@@ -1136,22 +1136,6 @@
};
-class LInstanceOf final : public LTemplateInstruction<1, 3, 0> {
- public:
- LInstanceOf(LOperand* context, LOperand* left, LOperand* right) {
- inputs_[0] = context;
- inputs_[1] = left;
- inputs_[2] = right;
- }
-
- LOperand* context() { return inputs_[0]; }
- LOperand* left() { return inputs_[1]; }
- LOperand* right() { return inputs_[2]; }
-
- DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
-};
-
-
class LHasInPrototypeChainAndBranch final : public LControlInstruction<2, 0> {
public:
LHasInPrototypeChainAndBranch(LOperand* object, LOperand* prototype) {
@@ -2385,6 +2369,19 @@
DECLARE_HYDROGEN_ACCESSOR(Allocate)
};
+class LFastAllocate final : public LTemplateInstruction<1, 1, 1> {
+ public:
+ LFastAllocate(LOperand* size, LOperand* temp) {
+ inputs_[0] = size;
+ temps_[0] = temp;
+ }
+
+ LOperand* size() const { return inputs_[0]; }
+ LOperand* temp() { return temps_[0]; }
+
+ DECLARE_CONCRETE_INSTRUCTION(FastAllocate, "fast-allocate")
+ DECLARE_HYDROGEN_ACCESSOR(Allocate)
+};
class LTypeof final : public LTemplateInstruction<1, 2, 0> {
public: