Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE
This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.
FPIIM-449
Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 5f80b4d..12daec8 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -120,29 +120,62 @@
Push(isolate()->heap()->root_handle(index));
}
+#define REG(Name) \
+ { Register::kCode_##Name }
-void MacroAssembler::InNewSpace(
- Register object,
- Register scratch,
- Condition cc,
- Label* condition_met,
- Label::Distance condition_met_distance) {
- DCHECK(cc == equal || cc == not_equal);
- if (scratch.is(object)) {
- and_(scratch, Immediate(~Page::kPageAlignmentMask));
- } else {
- mov(scratch, Immediate(~Page::kPageAlignmentMask));
- and_(scratch, object);
+static const Register saved_regs[] = {REG(eax), REG(ecx), REG(edx)};
+
+#undef REG
+
+static const int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register);
+
+void MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode,
+ Register exclusion1, Register exclusion2,
+ Register exclusion3) {
+ // We don't allow a GC during a store buffer overflow so there is no need to
+ // store the registers in any particular way, but we do have to store and
+ // restore them.
+ for (int i = 0; i < kNumberOfSavedRegs; i++) {
+ Register reg = saved_regs[i];
+ if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) {
+ push(reg);
+ }
}
- // Check that we can use a test_b.
- DCHECK(MemoryChunk::IN_FROM_SPACE < 8);
- DCHECK(MemoryChunk::IN_TO_SPACE < 8);
- int mask = (1 << MemoryChunk::IN_FROM_SPACE)
- | (1 << MemoryChunk::IN_TO_SPACE);
- // If non-zero, the page belongs to new-space.
- test_b(Operand(scratch, MemoryChunk::kFlagsOffset),
- static_cast<uint8_t>(mask));
- j(cc, condition_met, condition_met_distance);
+ if (fp_mode == kSaveFPRegs) {
+ sub(esp, Immediate(kDoubleSize * (XMMRegister::kMaxNumRegisters - 1)));
+ // Save all XMM registers except XMM0.
+ for (int i = XMMRegister::kMaxNumRegisters - 1; i > 0; i--) {
+ XMMRegister reg = XMMRegister::from_code(i);
+ movsd(Operand(esp, (i - 1) * kDoubleSize), reg);
+ }
+ }
+}
+
+void MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1,
+ Register exclusion2, Register exclusion3) {
+ if (fp_mode == kSaveFPRegs) {
+ // Restore all XMM registers except XMM0.
+ for (int i = XMMRegister::kMaxNumRegisters - 1; i > 0; i--) {
+ XMMRegister reg = XMMRegister::from_code(i);
+ movsd(reg, Operand(esp, (i - 1) * kDoubleSize));
+ }
+ add(esp, Immediate(kDoubleSize * (XMMRegister::kMaxNumRegisters - 1)));
+ }
+
+ for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) {
+ Register reg = saved_regs[i];
+ if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) {
+ pop(reg);
+ }
+ }
+}
+
+void MacroAssembler::InNewSpace(Register object, Register scratch, Condition cc,
+ Label* condition_met,
+ Label::Distance distance) {
+ const int mask =
+ (1 << MemoryChunk::IN_FROM_SPACE) | (1 << MemoryChunk::IN_TO_SPACE);
+ CheckPageFlag(object, scratch, mask, cc, condition_met, distance);
}
@@ -571,6 +604,75 @@
}
}
+void MacroAssembler::RecordWriteCodeEntryField(Register js_function,
+ Register code_entry,
+ Register scratch) {
+ const int offset = JSFunction::kCodeEntryOffset;
+
+ // Since a code entry (value) is always in old space, we don't need to update
+ // remembered set. If incremental marking is off, there is nothing for us to
+ // do.
+ if (!FLAG_incremental_marking) return;
+
+ DCHECK(!js_function.is(code_entry));
+ DCHECK(!js_function.is(scratch));
+ DCHECK(!code_entry.is(scratch));
+ AssertNotSmi(js_function);
+
+ if (emit_debug_code()) {
+ Label ok;
+ lea(scratch, FieldOperand(js_function, offset));
+ cmp(code_entry, Operand(scratch, 0));
+ j(equal, &ok, Label::kNear);
+ int3();
+ bind(&ok);
+ }
+
+ // First, check if a write barrier is even needed. The tests below
+ // catch stores of Smis and stores into young gen.
+ Label done;
+
+ CheckPageFlag(code_entry, scratch,
+ MemoryChunk::kPointersToHereAreInterestingMask, zero, &done,
+ Label::kNear);
+ CheckPageFlag(js_function, scratch,
+ MemoryChunk::kPointersFromHereAreInterestingMask, zero, &done,
+ Label::kNear);
+
+ // Save input registers.
+ push(js_function);
+ push(code_entry);
+
+ const Register dst = scratch;
+ lea(dst, FieldOperand(js_function, offset));
+
+ // Save caller-saved registers.
+ PushCallerSaved(kDontSaveFPRegs, js_function, code_entry);
+
+ int argument_count = 3;
+ PrepareCallCFunction(argument_count, code_entry);
+ mov(Operand(esp, 0 * kPointerSize), js_function);
+ mov(Operand(esp, 1 * kPointerSize), dst); // Slot.
+ mov(Operand(esp, 2 * kPointerSize),
+ Immediate(ExternalReference::isolate_address(isolate())));
+
+ {
+ AllowExternalCallThatCantCauseGC scope(this);
+ CallCFunction(
+ ExternalReference::incremental_marking_record_write_code_entry_function(
+ isolate()),
+ argument_count);
+ }
+
+ // Restore caller-saved registers.
+ PopCallerSaved(kDontSaveFPRegs, js_function, code_entry);
+
+ // Restore input registers.
+ pop(code_entry);
+ pop(js_function);
+
+ bind(&done);
+}
void MacroAssembler::DebugBreak() {
Move(eax, Immediate(0));
@@ -587,6 +689,25 @@
}
+void MacroAssembler::Cvtui2ss(XMMRegister dst, Register src, Register tmp) {
+ Label msb_set_src;
+ Label jmp_return;
+ test(src, src);
+ j(sign, &msb_set_src, Label::kNear);
+ cvtsi2ss(dst, src);
+ jmp(&jmp_return, Label::kNear);
+ bind(&msb_set_src);
+ mov(tmp, src);
+ shr(src, 1);
+ // Recover the least significant bit to avoid rounding errors.
+ and_(tmp, Immediate(1));
+ or_(src, tmp);
+ cvtsi2ss(dst, src);
+ addss(dst, dst);
+ bind(&jmp_return);
+}
+
+
bool MacroAssembler::IsUnsafeImmediate(const Immediate& x) {
static const int kMaxImmediateBits = 17;
if (!RelocInfo::IsNone(x.rmode_)) return false;
@@ -833,6 +954,19 @@
}
+void MacroAssembler::AssertReceiver(Register object) {
+ if (emit_debug_code()) {
+ test(object, Immediate(kSmiTagMask));
+ Check(not_equal, kOperandIsASmiAndNotAReceiver);
+ Push(object);
+ STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
+ CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, object);
+ Pop(object);
+ Check(above_equal, kOperandIsNotAReceiver);
+ }
+}
+
+
void MacroAssembler::AssertUndefinedOrAllocationSite(Register object) {
if (emit_debug_code()) {
Label done_checking;
@@ -967,7 +1101,7 @@
}
-void MacroAssembler::EnterExitFrame(bool save_doubles) {
+void MacroAssembler::EnterExitFrame(int argc, bool save_doubles) {
EnterExitFramePrologue();
// Set up argc and argv in callee-saved registers.
@@ -976,7 +1110,7 @@
lea(esi, Operand(ebp, eax, times_4, offset));
// Reserve space for argc, argv and isolate.
- EnterExitFrameEpilogue(3, save_doubles);
+ EnterExitFrameEpilogue(argc, save_doubles);
}
@@ -1768,13 +1902,13 @@
Register end_address,
Register filler) {
Label loop, entry;
- jmp(&entry);
+ jmp(&entry, Label::kNear);
bind(&loop);
mov(Operand(current_address, 0), filler);
add(current_address, Immediate(kPointerSize));
bind(&entry);
cmp(current_address, end_address);
- j(below, &loop);
+ j(below, &loop, Label::kNear);
}
@@ -1796,9 +1930,9 @@
Label* then_label) {
Label ok;
test(result, result);
- j(not_zero, &ok);
+ j(not_zero, &ok, Label::kNear);
test(op, op);
- j(sign, then_label);
+ j(sign, then_label, Label::kNear);
bind(&ok);
}
@@ -1810,10 +1944,10 @@
Label* then_label) {
Label ok;
test(result, result);
- j(not_zero, &ok);
+ j(not_zero, &ok, Label::kNear);
mov(scratch, op1);
or_(scratch, op2);
- j(sign, then_label);
+ j(sign, then_label, Label::kNear);
bind(&ok);
}
@@ -2044,7 +2178,7 @@
}
Push(fun);
Push(fun);
- CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1);
+ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
Pop(fun);
if (new_target.is_valid()) {
Pop(new_target);
@@ -2147,26 +2281,6 @@
}
-void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
- const CallWrapper& call_wrapper) {
- // You can't call a builtin without a valid frame.
- DCHECK(flag == JUMP_FUNCTION || has_frame());
-
- // Fake a parameter count to avoid emitting code to do the check.
- ParameterCount expected(0);
- GetBuiltinFunction(edi, native_context_index);
- InvokeFunctionCode(edi, no_reg, expected, expected, flag, call_wrapper);
-}
-
-
-void MacroAssembler::GetBuiltinFunction(Register target,
- int native_context_index) {
- // Load the JavaScript builtin function from the builtins object.
- mov(target, NativeContextOperand());
- mov(target, ContextOperand(target, native_context_index));
-}
-
-
void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
if (context_chain_length > 0) {
// Move up the chain of contexts to the context containing the slot.
@@ -2641,9 +2755,9 @@
// We don't actually want to generate a pile of code for this, so just
// claim there is a stack frame, without generating one.
FrameScope scope(this, StackFrame::NONE);
- CallRuntime(Runtime::kAbort, 1);
+ CallRuntime(Runtime::kAbort);
} else {
- CallRuntime(Runtime::kAbort, 1);
+ CallRuntime(Runtime::kAbort);
}
// will not return here
int3();