| Index: src/mips/macro-assembler-mips.cc
|
| diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
|
| index 8d85aed0ba226b708948bf61e13e9495e7d30594..1c22a89e156bec424701803d27d26e0d8baeeae1 100644
|
| --- a/src/mips/macro-assembler-mips.cc
|
| +++ b/src/mips/macro-assembler-mips.cc
|
| @@ -1563,19 +1563,27 @@ void MacroAssembler::Branch(Label* L, Condition cond, Register rs,
|
| if (is_near(L)) {
|
| BranchShort(L, cond, rs, rt, bdslot);
|
| } else {
|
| - Label skip;
|
| - Condition neg_cond = NegateCondition(cond);
|
| - BranchShort(&skip, neg_cond, rs, rt);
|
| - Jr(L, bdslot);
|
| - bind(&skip);
|
| + if (cond != cc_always) {
|
| + Label skip;
|
| + Condition neg_cond = NegateCondition(cond);
|
| + BranchShort(&skip, neg_cond, rs, rt);
|
| + Jr(L, bdslot);
|
| + bind(&skip);
|
| + } else {
|
| + Jr(L, bdslot);
|
| + }
|
| }
|
| } else {
|
| if (is_trampoline_emitted()) {
|
| - Label skip;
|
| - Condition neg_cond = NegateCondition(cond);
|
| - BranchShort(&skip, neg_cond, rs, rt);
|
| - Jr(L, bdslot);
|
| - bind(&skip);
|
| + if (cond != cc_always) {
|
| + Label skip;
|
| + Condition neg_cond = NegateCondition(cond);
|
| + BranchShort(&skip, neg_cond, rs, rt);
|
| + Jr(L, bdslot);
|
| + bind(&skip);
|
| + } else {
|
| + Jr(L, bdslot);
|
| + }
|
| } else {
|
| BranchShort(L, cond, rs, rt, bdslot);
|
| }
|
| @@ -2844,7 +2852,7 @@ void MacroAssembler::Allocate(int object_size,
|
| Register scratch2,
|
| Label* gc_required,
|
| AllocationFlags flags) {
|
| - ASSERT(object_size <= Page::kMaxNonCodeHeapObjectSize);
|
| + ASSERT(object_size <= Page::kMaxRegularHeapObjectSize);
|
| if (!FLAG_inline_new) {
|
| if (emit_debug_code()) {
|
| // Trash the registers to simulate an allocation failure.
|
| @@ -3431,10 +3439,9 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
|
| Branch(&have_double_value, eq, mantissa_reg, Operand(zero_reg));
|
| bind(&is_nan);
|
| // Load canonical NaN for storing into the double array.
|
| - uint64_t nan_int64 = BitCast<uint64_t>(
|
| - FixedDoubleArray::canonical_not_the_hole_nan_as_double());
|
| - li(mantissa_reg, Operand(static_cast<uint32_t>(nan_int64)));
|
| - li(exponent_reg, Operand(static_cast<uint32_t>(nan_int64 >> 32)));
|
| + LoadRoot(at, Heap::kNanValueRootIndex);
|
| + lw(mantissa_reg, FieldMemOperand(at, HeapNumber::kMantissaOffset));
|
| + lw(exponent_reg, FieldMemOperand(at, HeapNumber::kExponentOffset));
|
| jmp(&have_double_value);
|
|
|
| bind(&smi_value);
|
| @@ -3872,10 +3879,8 @@ static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
|
|
|
|
|
| void MacroAssembler::CallApiFunctionAndReturn(
|
| - ExternalReference function,
|
| - Address function_address,
|
| + Register function_address,
|
| ExternalReference thunk_ref,
|
| - Register thunk_last_arg,
|
| int stack_space,
|
| MemOperand return_value_operand,
|
| MemOperand* context_restore_operand) {
|
| @@ -3889,6 +3894,25 @@ void MacroAssembler::CallApiFunctionAndReturn(
|
| ExternalReference::handle_scope_level_address(isolate()),
|
| next_address);
|
|
|
| + ASSERT(function_address.is(a1) || function_address.is(a2));
|
| +
|
| + Label profiler_disabled;
|
| + Label end_profiler_check;
|
| + bool* is_profiling_flag =
|
| + isolate()->cpu_profiler()->is_profiling_address();
|
| + STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
|
| + li(t9, reinterpret_cast<int32_t>(is_profiling_flag));
|
| + lb(t9, MemOperand(t9, 0));
|
| + Branch(&profiler_disabled, eq, t9, Operand(zero_reg));
|
| +
|
| + // Additional parameter is the address of the actual callback.
|
| + li(t9, Operand(thunk_ref));
|
| + jmp(&end_profiler_check);
|
| +
|
| + bind(&profiler_disabled);
|
| + mov(t9, function_address);
|
| + bind(&end_profiler_check);
|
| +
|
| // Allocate HandleScope in callee-save registers.
|
| li(s3, Operand(next_address));
|
| lw(s0, MemOperand(s3, kNextOffset));
|
| @@ -3906,25 +3930,6 @@ void MacroAssembler::CallApiFunctionAndReturn(
|
| PopSafepointRegisters();
|
| }
|
|
|
| - Label profiler_disabled;
|
| - Label end_profiler_check;
|
| - bool* is_profiling_flag =
|
| - isolate()->cpu_profiler()->is_profiling_address();
|
| - STATIC_ASSERT(sizeof(*is_profiling_flag) == 1);
|
| - li(t9, reinterpret_cast<int32_t>(is_profiling_flag));
|
| - lb(t9, MemOperand(t9, 0));
|
| - beq(t9, zero_reg, &profiler_disabled);
|
| -
|
| - // Third parameter is the address of the actual getter function.
|
| - li(thunk_last_arg, reinterpret_cast<int32_t>(function_address));
|
| - li(t9, Operand(thunk_ref));
|
| - jmp(&end_profiler_check);
|
| -
|
| - bind(&profiler_disabled);
|
| - li(t9, Operand(function));
|
| -
|
| - bind(&end_profiler_check);
|
| -
|
| // Native call returns to the DirectCEntry stub which redirects to the
|
| // return address pushed on stack (could have moved after GC).
|
| // DirectCEntry stub itself is generated early and never moves.
|
| @@ -4341,16 +4346,8 @@ void MacroAssembler::Check(Condition cc, BailoutReason reason,
|
| void MacroAssembler::Abort(BailoutReason reason) {
|
| Label abort_start;
|
| bind(&abort_start);
|
| - // We want to pass the msg string like a smi to avoid GC
|
| - // problems, however msg is not guaranteed to be aligned
|
| - // properly. Instead, we pass an aligned pointer that is
|
| - // a proper v8 smi, but also pass the alignment difference
|
| - // from the real pointer as a smi.
|
| - const char* msg = GetBailoutReason(reason);
|
| - intptr_t p1 = reinterpret_cast<intptr_t>(msg);
|
| - intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
|
| - ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
|
| #ifdef DEBUG
|
| + const char* msg = GetBailoutReason(reason);
|
| if (msg != NULL) {
|
| RecordComment("Abort message: ");
|
| RecordComment(msg);
|
| @@ -4362,18 +4359,16 @@ void MacroAssembler::Abort(BailoutReason reason) {
|
| }
|
| #endif
|
|
|
| - li(a0, Operand(p0));
|
| - push(a0);
|
| - li(a0, Operand(Smi::FromInt(p1 - p0)));
|
| + li(a0, Operand(Smi::FromInt(reason)));
|
| push(a0);
|
| // Disable stub call restrictions to always allow calls to abort.
|
| if (!has_frame_) {
|
| // 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, 2);
|
| + CallRuntime(Runtime::kAbort, 1);
|
| } else {
|
| - CallRuntime(Runtime::kAbort, 2);
|
| + CallRuntime(Runtime::kAbort, 1);
|
| }
|
| // Will not return here.
|
| if (is_trampoline_pool_blocked()) {
|
| @@ -4381,8 +4376,8 @@ void MacroAssembler::Abort(BailoutReason reason) {
|
| // instructions generated, we insert padding here to keep the size
|
| // of the Abort macro constant.
|
| // Currently in debug mode with debug_code enabled the number of
|
| - // generated instructions is 14, so we use this as a maximum value.
|
| - static const int kExpectedAbortInstructions = 14;
|
| + // generated instructions is 10, so we use this as a maximum value.
|
| + static const int kExpectedAbortInstructions = 10;
|
| int abort_instructions = InstructionsGeneratedSince(&abort_start);
|
| ASSERT(abort_instructions <= kExpectedAbortInstructions);
|
| while (abort_instructions++ < kExpectedAbortInstructions) {
|
| @@ -4435,31 +4430,6 @@ void MacroAssembler::LoadTransitionedArrayMapConditional(
|
| }
|
|
|
|
|
| -void MacroAssembler::LoadInitialArrayMap(
|
| - Register function_in, Register scratch,
|
| - Register map_out, bool can_have_holes) {
|
| - ASSERT(!function_in.is(map_out));
|
| - Label done;
|
| - lw(map_out, FieldMemOperand(function_in,
|
| - JSFunction::kPrototypeOrInitialMapOffset));
|
| - if (!FLAG_smi_only_arrays) {
|
| - ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS;
|
| - LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
| - kind,
|
| - map_out,
|
| - scratch,
|
| - &done);
|
| - } else if (can_have_holes) {
|
| - LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS,
|
| - FAST_HOLEY_SMI_ELEMENTS,
|
| - map_out,
|
| - scratch,
|
| - &done);
|
| - }
|
| - bind(&done);
|
| -}
|
| -
|
| -
|
| void MacroAssembler::LoadGlobalFunction(int index, Register function) {
|
| // Load the global or builtins object from the current context.
|
| lw(function,
|
| @@ -4472,19 +4442,6 @@ void MacroAssembler::LoadGlobalFunction(int index, Register function) {
|
| }
|
|
|
|
|
| -void MacroAssembler::LoadArrayFunction(Register function) {
|
| - // Load the global or builtins object from the current context.
|
| - lw(function,
|
| - MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
| - // Load the global context from the global or builtins object.
|
| - lw(function,
|
| - FieldMemOperand(function, GlobalObject::kGlobalContextOffset));
|
| - // Load the array function from the native context.
|
| - lw(function,
|
| - MemOperand(function, Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
|
| -}
|
| -
|
| -
|
| void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
|
| Register map,
|
| Register scratch) {
|
| @@ -5050,14 +5007,14 @@ void MacroAssembler::EmitSeqStringSetCharCheck(Register string,
|
| uint32_t encoding_mask) {
|
| Label is_object;
|
| SmiTst(string, at);
|
| - ThrowIf(eq, kNonObject, at, Operand(zero_reg));
|
| + Check(ne, kNonObject, at, Operand(zero_reg));
|
|
|
| lw(at, FieldMemOperand(string, HeapObject::kMapOffset));
|
| lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset));
|
|
|
| andi(at, at, kStringRepresentationMask | kStringEncodingMask);
|
| li(scratch, Operand(encoding_mask));
|
| - ThrowIf(ne, kUnexpectedStringType, at, Operand(scratch));
|
| + Check(eq, kUnexpectedStringType, at, Operand(scratch));
|
|
|
| // The index is assumed to be untagged coming in, tag it to compare with the
|
| // string length without using a temp register, it is restored at the end of
|
| @@ -5066,14 +5023,14 @@ void MacroAssembler::EmitSeqStringSetCharCheck(Register string,
|
| TrySmiTag(index, scratch, &index_tag_bad);
|
| Branch(&index_tag_ok);
|
| bind(&index_tag_bad);
|
| - Throw(kIndexIsTooLarge);
|
| + Abort(kIndexIsTooLarge);
|
| bind(&index_tag_ok);
|
|
|
| lw(at, FieldMemOperand(string, String::kLengthOffset));
|
| - ThrowIf(ge, kIndexIsTooLarge, index, Operand(at));
|
| + Check(lt, kIndexIsTooLarge, index, Operand(at));
|
|
|
| ASSERT(Smi::FromInt(0) == 0);
|
| - ThrowIf(lt, kIndexIsNegative, index, Operand(zero_reg));
|
| + Check(ge, kIndexIsNegative, index, Operand(zero_reg));
|
|
|
| SmiUntag(index, index);
|
| }
|
| @@ -5554,11 +5511,17 @@ void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
|
|
|
| bind(&start);
|
|
|
| - // Check that there are no elements. Register r2 contains the current JS
|
| + // Check that there are no elements. Register a2 contains the current JS
|
| // object we've reached through the prototype chain.
|
| + Label no_elements;
|
| lw(a2, FieldMemOperand(a2, JSObject::kElementsOffset));
|
| - Branch(call_runtime, ne, a2, Operand(empty_fixed_array_value));
|
| + Branch(&no_elements, eq, a2, Operand(empty_fixed_array_value));
|
| +
|
| + // Second chance, the object may be using the empty slow element dictionary.
|
| + LoadRoot(at, Heap::kEmptySlowElementDictionaryRootIndex);
|
| + Branch(call_runtime, ne, a2, Operand(at));
|
|
|
| + bind(&no_elements);
|
| lw(a2, FieldMemOperand(a1, Map::kPrototypeOffset));
|
| Branch(&next, ne, a2, Operand(null_value));
|
| }
|
|
|