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/x87/macro-assembler-x87.cc b/src/x87/macro-assembler-x87.cc
index 7a0beb5..0c459eb 100644
--- a/src/x87/macro-assembler-x87.cc
+++ b/src/x87/macro-assembler-x87.cc
@@ -120,29 +120,56 @@
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) {
+ // Save FPU state in m108byte.
+ sub(esp, Immediate(108));
+ fnsave(Operand(esp, 0));
+ }
+}
+
+void MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1,
+ Register exclusion2, Register exclusion3) {
+ if (fp_mode == kSaveFPRegs) {
+ // Restore FPU state in m108byte.
+ frstor(Operand(esp, 0));
+ add(esp, Immediate(108));
+ }
+
+ 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);
}
@@ -492,6 +519,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));
@@ -804,6 +900,17 @@
}
}
+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()) {
@@ -936,7 +1043,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.
@@ -945,7 +1052,7 @@
lea(esi, Operand(ebp, eax, times_4, offset));
// Reserve space for argc, argv and isolate.
- EnterExitFrameEpilogue(3, save_doubles);
+ EnterExitFrameEpilogue(argc, save_doubles);
}
@@ -1734,13 +1841,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);
}
@@ -1762,9 +1869,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);
}
@@ -1776,10 +1883,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);
}
@@ -2009,7 +2116,7 @@
}
Push(fun);
Push(fun);
- CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1);
+ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
Pop(fun);
if (new_target.is_valid()) {
Pop(new_target);
@@ -2111,26 +2218,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.
@@ -2524,9 +2611,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();