Upgrade V8 to 5.1.281.57 DO NOT MERGE
FPIIM-449
Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 80aef0c..6af3d6c 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -738,12 +738,12 @@
str(scratch, MemOperand(ip));
// Call stub on end of buffer.
// Check for end of buffer.
- tst(scratch, Operand(StoreBuffer::kStoreBufferOverflowBit));
+ tst(scratch, Operand(StoreBuffer::kStoreBufferMask));
if (and_then == kFallThroughAtEnd) {
- b(eq, &done);
+ b(ne, &done);
} else {
DCHECK(and_then == kReturnAtEnd);
- Ret(eq);
+ Ret(ne);
}
push(lr);
StoreBufferOverflowStub store_buffer_overflow(isolate(), fp_mode);
@@ -755,20 +755,65 @@
}
}
-
-void MacroAssembler::PushFixedFrame(Register marker_reg) {
- DCHECK(!marker_reg.is_valid() || marker_reg.code() < cp.code());
- stm(db_w, sp, (marker_reg.is_valid() ? marker_reg.bit() : 0) | cp.bit() |
- (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) |
- fp.bit() | lr.bit());
+void MacroAssembler::PushCommonFrame(Register marker_reg) {
+ if (marker_reg.is_valid()) {
+ if (FLAG_enable_embedded_constant_pool) {
+ if (marker_reg.code() > pp.code()) {
+ stm(db_w, sp, pp.bit() | fp.bit() | lr.bit());
+ add(fp, sp, Operand(kPointerSize));
+ Push(marker_reg);
+ } else {
+ stm(db_w, sp, marker_reg.bit() | pp.bit() | fp.bit() | lr.bit());
+ add(fp, sp, Operand(2 * kPointerSize));
+ }
+ } else {
+ if (marker_reg.code() > fp.code()) {
+ stm(db_w, sp, fp.bit() | lr.bit());
+ mov(fp, Operand(sp));
+ Push(marker_reg);
+ } else {
+ stm(db_w, sp, marker_reg.bit() | fp.bit() | lr.bit());
+ add(fp, sp, Operand(kPointerSize));
+ }
+ }
+ } else {
+ stm(db_w, sp, (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) |
+ fp.bit() | lr.bit());
+ add(fp, sp, Operand(FLAG_enable_embedded_constant_pool ? kPointerSize : 0));
+ }
}
+void MacroAssembler::PopCommonFrame(Register marker_reg) {
+ if (marker_reg.is_valid()) {
+ if (FLAG_enable_embedded_constant_pool) {
+ if (marker_reg.code() > pp.code()) {
+ pop(marker_reg);
+ ldm(ia_w, sp, pp.bit() | fp.bit() | lr.bit());
+ } else {
+ ldm(ia_w, sp, marker_reg.bit() | pp.bit() | fp.bit() | lr.bit());
+ }
+ } else {
+ if (marker_reg.code() > fp.code()) {
+ pop(marker_reg);
+ ldm(ia_w, sp, fp.bit() | lr.bit());
+ } else {
+ ldm(ia_w, sp, marker_reg.bit() | fp.bit() | lr.bit());
+ }
+ }
+ } else {
+ ldm(ia_w, sp, (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) |
+ fp.bit() | lr.bit());
+ }
+}
-void MacroAssembler::PopFixedFrame(Register marker_reg) {
- DCHECK(!marker_reg.is_valid() || marker_reg.code() < cp.code());
- ldm(ia_w, sp, (marker_reg.is_valid() ? marker_reg.bit() : 0) | cp.bit() |
+void MacroAssembler::PushStandardFrame(Register function_reg) {
+ DCHECK(!function_reg.is_valid() || function_reg.code() < cp.code());
+ stm(db_w, sp, (function_reg.is_valid() ? function_reg.bit() : 0) | cp.bit() |
(FLAG_enable_embedded_constant_pool ? pp.bit() : 0) |
fp.bit() | lr.bit());
+ int offset = -StandardFrameConstants::kContextOffset;
+ offset += function_reg.is_valid() ? kPointerSize : 0;
+ add(fp, sp, Operand(offset));
}
@@ -1056,7 +1101,144 @@
vmov(dst, VmovIndexLo, src);
}
}
+void MacroAssembler::LslPair(Register dst_low, Register dst_high,
+ Register src_low, Register src_high,
+ Register scratch, Register shift) {
+ DCHECK(!AreAliased(dst_high, src_low));
+ DCHECK(!AreAliased(dst_high, shift));
+ Label less_than_32;
+ Label done;
+ rsb(scratch, shift, Operand(32), SetCC);
+ b(gt, &less_than_32);
+ // If shift >= 32
+ and_(scratch, shift, Operand(0x1f));
+ lsl(dst_high, src_low, Operand(scratch));
+ mov(dst_low, Operand(0));
+ jmp(&done);
+ bind(&less_than_32);
+ // If shift < 32
+ lsl(dst_high, src_high, Operand(shift));
+ orr(dst_high, dst_high, Operand(src_low, LSR, scratch));
+ lsl(dst_low, src_low, Operand(shift));
+ bind(&done);
+}
+
+void MacroAssembler::LslPair(Register dst_low, Register dst_high,
+ Register src_low, Register src_high,
+ uint32_t shift) {
+ DCHECK(!AreAliased(dst_high, src_low));
+ Label less_than_32;
+ Label done;
+ if (shift == 0) {
+ Move(dst_high, src_high);
+ Move(dst_low, src_low);
+ } else if (shift == 32) {
+ Move(dst_high, src_low);
+ Move(dst_low, Operand(0));
+ } else if (shift >= 32) {
+ shift &= 0x1f;
+ lsl(dst_high, src_low, Operand(shift));
+ mov(dst_low, Operand(0));
+ } else {
+ lsl(dst_high, src_high, Operand(shift));
+ orr(dst_high, dst_high, Operand(src_low, LSR, 32 - shift));
+ lsl(dst_low, src_low, Operand(shift));
+ }
+}
+
+void MacroAssembler::LsrPair(Register dst_low, Register dst_high,
+ Register src_low, Register src_high,
+ Register scratch, Register shift) {
+ DCHECK(!AreAliased(dst_low, src_high));
+ DCHECK(!AreAliased(dst_low, shift));
+
+ Label less_than_32;
+ Label done;
+ rsb(scratch, shift, Operand(32), SetCC);
+ b(gt, &less_than_32);
+ // If shift >= 32
+ and_(scratch, shift, Operand(0x1f));
+ lsr(dst_low, src_high, Operand(scratch));
+ mov(dst_high, Operand(0));
+ jmp(&done);
+ bind(&less_than_32);
+ // If shift < 32
+
+ lsr(dst_low, src_low, Operand(shift));
+ orr(dst_low, dst_low, Operand(src_high, LSL, scratch));
+ lsr(dst_high, src_high, Operand(shift));
+ bind(&done);
+}
+
+void MacroAssembler::LsrPair(Register dst_low, Register dst_high,
+ Register src_low, Register src_high,
+ uint32_t shift) {
+ DCHECK(!AreAliased(dst_low, src_high));
+ Label less_than_32;
+ Label done;
+ if (shift == 32) {
+ mov(dst_low, src_high);
+ mov(dst_high, Operand(0));
+ } else if (shift > 32) {
+ shift &= 0x1f;
+ lsr(dst_low, src_high, Operand(shift));
+ mov(dst_high, Operand(0));
+ } else if (shift == 0) {
+ Move(dst_low, src_low);
+ Move(dst_high, src_high);
+ } else {
+ lsr(dst_low, src_low, Operand(shift));
+ orr(dst_low, dst_low, Operand(src_high, LSL, 32 - shift));
+ lsr(dst_high, src_high, Operand(shift));
+ }
+}
+
+void MacroAssembler::AsrPair(Register dst_low, Register dst_high,
+ Register src_low, Register src_high,
+ Register scratch, Register shift) {
+ DCHECK(!AreAliased(dst_low, src_high));
+ DCHECK(!AreAliased(dst_low, shift));
+
+ Label less_than_32;
+ Label done;
+ rsb(scratch, shift, Operand(32), SetCC);
+ b(gt, &less_than_32);
+ // If shift >= 32
+ and_(scratch, shift, Operand(0x1f));
+ asr(dst_low, src_high, Operand(scratch));
+ asr(dst_high, src_high, Operand(31));
+ jmp(&done);
+ bind(&less_than_32);
+ // If shift < 32
+ lsr(dst_low, src_low, Operand(shift));
+ orr(dst_low, dst_low, Operand(src_high, LSL, scratch));
+ asr(dst_high, src_high, Operand(shift));
+ bind(&done);
+}
+
+void MacroAssembler::AsrPair(Register dst_low, Register dst_high,
+ Register src_low, Register src_high,
+ uint32_t shift) {
+ DCHECK(!AreAliased(dst_low, src_high));
+ Label less_than_32;
+ Label done;
+ if (shift == 32) {
+ mov(dst_low, src_high);
+ asr(dst_high, src_high, Operand(31));
+ } else if (shift > 32) {
+ shift &= 0x1f;
+ asr(dst_low, src_high, Operand(shift));
+ asr(dst_high, src_high, Operand(31));
+ } else if (shift == 0) {
+ Move(dst_low, src_low);
+ Move(dst_high, src_high);
+ } else {
+ lsr(dst_low, src_low, Operand(shift));
+ orr(dst_low, dst_low, Operand(src_high, LSL, 32 - shift));
+ asr(dst_high, src_high, Operand(shift));
+ }
+}
void MacroAssembler::LoadConstantPoolPointerRegisterFromCodeTargetAddress(
Register code_target_address) {
@@ -1074,19 +1256,15 @@
LoadConstantPoolPointerRegisterFromCodeTargetAddress(ip);
}
-
-void MacroAssembler::StubPrologue() {
- PushFixedFrame();
- Push(Smi::FromInt(StackFrame::STUB));
- // Adjust FP to point to saved FP.
- add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+void MacroAssembler::StubPrologue(StackFrame::Type type) {
+ mov(ip, Operand(Smi::FromInt(type)));
+ PushCommonFrame(ip);
if (FLAG_enable_embedded_constant_pool) {
LoadConstantPoolPointerRegister();
set_constant_pool_available(true);
}
}
-
void MacroAssembler::Prologue(bool code_pre_aging) {
{ PredictableCodeSizeScope predictible_code_size_scope(
this, kNoCodeAgeSequenceLength);
@@ -1099,10 +1277,8 @@
ldr(pc, MemOperand(pc, -4));
emit_code_stub_address(stub);
} else {
- PushFixedFrame(r1);
+ PushStandardFrame(r1);
nop(ip.code());
- // Adjust FP to point to saved FP.
- add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
}
}
if (FLAG_enable_embedded_constant_pool) {
@@ -1123,17 +1299,15 @@
void MacroAssembler::EnterFrame(StackFrame::Type type,
bool load_constant_pool_pointer_reg) {
// r0-r3: preserved
- PushFixedFrame();
+ mov(ip, Operand(Smi::FromInt(type)));
+ PushCommonFrame(ip);
if (FLAG_enable_embedded_constant_pool && load_constant_pool_pointer_reg) {
LoadConstantPoolPointerRegister();
}
- mov(ip, Operand(Smi::FromInt(type)));
- push(ip);
- mov(ip, Operand(CodeObject()));
- push(ip);
- // Adjust FP to point to saved FP.
- add(fp, sp,
- Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
+ if (type == StackFrame::INTERNAL) {
+ mov(ip, Operand(CodeObject()));
+ push(ip);
+ }
}
@@ -1164,10 +1338,10 @@
DCHECK_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement);
DCHECK_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset);
DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset);
- Push(lr, fp);
- mov(fp, Operand(sp)); // Set up new frame pointer.
+ mov(ip, Operand(Smi::FromInt(StackFrame::EXIT)));
+ PushCommonFrame(ip);
// Reserve room for saved entry sp and code object.
- sub(sp, sp, Operand(ExitFrameConstants::kFrameSize));
+ sub(sp, fp, Operand(ExitFrameConstants::kFixedFrameSizeFromFp));
if (emit_debug_code()) {
mov(ip, Operand::Zero());
str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
@@ -1249,7 +1423,7 @@
// Optionally restore all double registers.
if (save_doubles) {
// Calculate the stack location of the saved doubles and restore them.
- const int offset = ExitFrameConstants::kFrameSize;
+ const int offset = ExitFrameConstants::kFixedFrameSizeFromFp;
sub(r3, fp,
Operand(offset + DwVfpRegister::kMaxNumRegisters * kDoubleSize));
RestoreFPRegs(r3, ip);
@@ -1300,6 +1474,64 @@
MovFromFloatResult(dst);
}
+void MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
+ Register caller_args_count_reg,
+ Register scratch0, Register scratch1) {
+#if DEBUG
+ if (callee_args_count.is_reg()) {
+ DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0,
+ scratch1));
+ } else {
+ DCHECK(!AreAliased(caller_args_count_reg, scratch0, scratch1));
+ }
+#endif
+
+ // Calculate the end of destination area where we will put the arguments
+ // after we drop current frame. We add kPointerSize to count the receiver
+ // argument which is not included into formal parameters count.
+ Register dst_reg = scratch0;
+ add(dst_reg, fp, Operand(caller_args_count_reg, LSL, kPointerSizeLog2));
+ add(dst_reg, dst_reg,
+ Operand(StandardFrameConstants::kCallerSPOffset + kPointerSize));
+
+ Register src_reg = caller_args_count_reg;
+ // Calculate the end of source area. +kPointerSize is for the receiver.
+ if (callee_args_count.is_reg()) {
+ add(src_reg, sp, Operand(callee_args_count.reg(), LSL, kPointerSizeLog2));
+ add(src_reg, src_reg, Operand(kPointerSize));
+ } else {
+ add(src_reg, sp,
+ Operand((callee_args_count.immediate() + 1) * kPointerSize));
+ }
+
+ if (FLAG_debug_code) {
+ cmp(src_reg, dst_reg);
+ Check(lo, kStackAccessBelowStackPointer);
+ }
+
+ // Restore caller's frame pointer and return address now as they will be
+ // overwritten by the copying loop.
+ ldr(lr, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
+ ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+
+ // Now copy callee arguments to the caller frame going backwards to avoid
+ // callee arguments corruption (source and destination areas could overlap).
+
+ // Both src_reg and dst_reg are pointing to the word after the one to copy,
+ // so they must be pre-decremented in the loop.
+ Register tmp_reg = scratch1;
+ Label loop, entry;
+ b(&entry);
+ bind(&loop);
+ ldr(tmp_reg, MemOperand(src_reg, -kPointerSize, PreIndex));
+ str(tmp_reg, MemOperand(dst_reg, -kPointerSize, PreIndex));
+ bind(&entry);
+ cmp(sp, src_reg);
+ b(ne, &loop);
+
+ // Leave current frame.
+ mov(sp, dst_reg);
+}
void MacroAssembler::InvokePrologue(const ParameterCount& expected,
const ParameterCount& actual,
@@ -1578,8 +1810,19 @@
DCHECK(!holder_reg.is(ip));
DCHECK(!scratch.is(ip));
- // Load current lexical context from the stack frame.
- ldr(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset));
+ // Load current lexical context from the active StandardFrame, which
+ // may require crawling past STUB frames.
+ Label load_context;
+ Label has_context;
+ DCHECK(!ip.is(scratch));
+ mov(ip, fp);
+ bind(&load_context);
+ ldr(scratch, MemOperand(ip, CommonFrameConstants::kContextOrFrameTypeOffset));
+ JumpIfNotSmi(scratch, &has_context);
+ ldr(ip, MemOperand(ip, CommonFrameConstants::kCallerFPOffset));
+ b(&load_context);
+ bind(&has_context);
+
// In debug mode, make sure the lexical context is set.
#ifdef DEBUG
cmp(scratch, Operand::Zero());
@@ -2803,6 +3046,17 @@
b(eq, on_either_smi);
}
+void MacroAssembler::AssertNotNumber(Register object) {
+ if (emit_debug_code()) {
+ STATIC_ASSERT(kSmiTag == 0);
+ tst(object, Operand(kSmiTagMask));
+ Check(ne, kOperandIsANumber);
+ push(object);
+ CompareObjectType(object, object, object, HEAP_NUMBER_TYPE);
+ pop(object);
+ Check(ne, kOperandIsANumber);
+ }
+}
void MacroAssembler::AssertNotSmi(Register object) {
if (emit_debug_code()) {
@@ -3510,28 +3764,45 @@
b(ne, &next);
}
-
void MacroAssembler::TestJSArrayForAllocationMemento(
Register receiver_reg,
Register scratch_reg,
Label* no_memento_found) {
- ExternalReference new_space_start =
- ExternalReference::new_space_start(isolate());
+ Label map_check;
+ Label top_check;
ExternalReference new_space_allocation_top =
ExternalReference::new_space_allocation_top_address(isolate());
- add(scratch_reg, receiver_reg,
- Operand(JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag));
- cmp(scratch_reg, Operand(new_space_start));
- b(lt, no_memento_found);
- mov(ip, Operand(new_space_allocation_top));
- ldr(ip, MemOperand(ip));
- cmp(scratch_reg, ip);
- b(gt, no_memento_found);
- ldr(scratch_reg, MemOperand(scratch_reg, -AllocationMemento::kSize));
- cmp(scratch_reg,
- Operand(isolate()->factory()->allocation_memento_map()));
-}
+ const int kMementoMapOffset = JSArray::kSize - kHeapObjectTag;
+ const int kMementoEndOffset = kMementoMapOffset + AllocationMemento::kSize;
+ // Bail out if the object is not in new space.
+ JumpIfNotInNewSpace(receiver_reg, scratch_reg, no_memento_found);
+ // If the object is in new space, we need to check whether it is on the same
+ // page as the current top.
+ add(scratch_reg, receiver_reg, Operand(kMementoEndOffset));
+ eor(scratch_reg, scratch_reg, Operand(new_space_allocation_top));
+ tst(scratch_reg, Operand(~Page::kPageAlignmentMask));
+ b(eq, &top_check);
+ // The object is on a different page than allocation top. Bail out if the
+ // object sits on the page boundary as no memento can follow and we cannot
+ // touch the memory following it.
+ add(scratch_reg, receiver_reg, Operand(kMementoEndOffset));
+ eor(scratch_reg, scratch_reg, Operand(receiver_reg));
+ tst(scratch_reg, Operand(~Page::kPageAlignmentMask));
+ b(ne, no_memento_found);
+ // Continue with the actual map check.
+ jmp(&map_check);
+ // If top is on the same page as the current object, we need to check whether
+ // we are below top.
+ bind(&top_check);
+ add(scratch_reg, receiver_reg, Operand(kMementoEndOffset));
+ cmp(scratch_reg, Operand(new_space_allocation_top));
+ b(gt, no_memento_found);
+ // Memento map check.
+ bind(&map_check);
+ ldr(scratch_reg, MemOperand(receiver_reg, kMementoMapOffset));
+ cmp(scratch_reg, Operand(isolate()->factory()->allocation_memento_map()));
+}
Register GetRegisterThatIsNotOneOf(Register reg1,
Register reg2,