| Index: src/mips/stub-cache-mips.cc
|
| ===================================================================
|
| --- src/mips/stub-cache-mips.cc (revision 11348)
|
| +++ src/mips/stub-cache-mips.cc (working copy)
|
| @@ -565,6 +565,8 @@
|
| __ Push(scratch, receiver, holder);
|
| __ lw(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset));
|
| __ push(scratch);
|
| + __ li(scratch, Operand(ExternalReference::isolate_address()));
|
| + __ push(scratch);
|
| }
|
|
|
|
|
| @@ -579,7 +581,7 @@
|
| ExternalReference ref =
|
| ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
|
| masm->isolate());
|
| - __ PrepareCEntryArgs(5);
|
| + __ PrepareCEntryArgs(6);
|
| __ PrepareCEntryFunction(ref);
|
|
|
| CEntryStub stub(1);
|
| @@ -587,10 +589,10 @@
|
| }
|
|
|
|
|
| -static const int kFastApiCallArguments = 3;
|
| +static const int kFastApiCallArguments = 4;
|
|
|
|
|
| -// Reserves space for the extra arguments to FastHandleApiCall in the
|
| +// Reserves space for the extra arguments to API function in the
|
| // caller's frame.
|
| //
|
| // These arguments are set by CheckPrototypes and GenerateFastApiDirectCall.
|
| @@ -616,7 +618,8 @@
|
| // -- sp[0] : holder (set by CheckPrototypes)
|
| // -- sp[4] : callee JS function
|
| // -- sp[8] : call data
|
| - // -- sp[12] : last JS argument
|
| + // -- sp[12] : isolate
|
| + // -- sp[16] : last JS argument
|
| // -- ...
|
| // -- sp[(argc + 3) * 4] : first JS argument
|
| // -- sp[(argc + 4) * 4] : receiver
|
| @@ -626,7 +629,7 @@
|
| __ LoadHeapObject(t1, function);
|
| __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset));
|
|
|
| - // Pass the additional arguments FastHandleApiCall expects.
|
| + // Pass the additional arguments.
|
| Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
|
| Handle<Object> call_data(api_call_info->data());
|
| if (masm->isolate()->heap()->InNewSpace(*call_data)) {
|
| @@ -636,14 +639,17 @@
|
| __ li(t2, call_data);
|
| }
|
|
|
| - // Store JS function and call data.
|
| + __ li(t3, Operand(ExternalReference::isolate_address()));
|
| + // Store JS function, call data and isolate.
|
| __ sw(t1, MemOperand(sp, 1 * kPointerSize));
|
| __ sw(t2, MemOperand(sp, 2 * kPointerSize));
|
| + __ sw(t3, MemOperand(sp, 3 * kPointerSize));
|
|
|
| - // a2 points to call data as expected by Arguments
|
| - // (refer to layout above).
|
| - __ Addu(a2, sp, Operand(2 * kPointerSize));
|
| + // Prepare arguments.
|
| + __ Addu(a2, sp, Operand(3 * kPointerSize));
|
|
|
| + // Allocate the v8::Arguments structure in the arguments' space since
|
| + // it's not controlled by GC.
|
| const int kApiStackSpace = 4;
|
|
|
| FrameScope frame_scope(masm, StackFrame::MANUAL);
|
| @@ -658,9 +664,9 @@
|
| // Arguments is built at sp + 1 (sp is a reserved spot for ra).
|
| __ Addu(a1, sp, kPointerSize);
|
|
|
| - // v8::Arguments::implicit_args = data
|
| + // v8::Arguments::implicit_args_
|
| __ sw(a2, MemOperand(a1, 0 * kPointerSize));
|
| - // v8::Arguments::values = last argument
|
| + // v8::Arguments::values_
|
| __ Addu(t0, a2, Operand(argc * kPointerSize));
|
| __ sw(t0, MemOperand(a1, 1 * kPointerSize));
|
| // v8::Arguments::length_ = argc
|
| @@ -838,7 +844,7 @@
|
| ExternalReference(
|
| IC_Utility(IC::kLoadPropertyWithInterceptorForCall),
|
| masm->isolate()),
|
| - 5);
|
| + 6);
|
| // Restore the name_ register.
|
| __ pop(name_);
|
| // Leave the internal frame.
|
| @@ -1207,7 +1213,13 @@
|
| } else {
|
| __ li(scratch3, Handle<Object>(callback->data()));
|
| }
|
| - __ Push(reg, scratch3, name_reg);
|
| + __ Subu(sp, sp, 4 * kPointerSize);
|
| + __ sw(reg, MemOperand(sp, 3 * kPointerSize));
|
| + __ sw(scratch3, MemOperand(sp, 2 * kPointerSize));
|
| + __ li(scratch3, Operand(ExternalReference::isolate_address()));
|
| + __ sw(scratch3, MemOperand(sp, 1 * kPointerSize));
|
| + __ sw(name_reg, MemOperand(sp, 0 * kPointerSize));
|
| +
|
| __ mov(a2, scratch2); // Saved in case scratch2 == a1.
|
| __ mov(a1, sp); // a1 (first argument - see note below) = Handle<String>
|
|
|
| @@ -1226,7 +1238,7 @@
|
| // a2 (second argument - see note above) = AccessorInfo&
|
| __ Addu(a2, sp, kPointerSize);
|
|
|
| - const int kStackUnwindSpace = 4;
|
| + const int kStackUnwindSpace = 5;
|
| Address getter_address = v8::ToCData<Address>(callback->getter());
|
| ApiFunction fun(getter_address);
|
| ExternalReference ref =
|
| @@ -1342,24 +1354,17 @@
|
| // Important invariant in CALLBACKS case: the code above must be
|
| // structured to never clobber |receiver| register.
|
| __ li(scratch2, callback);
|
| - // holder_reg is either receiver or scratch1.
|
| - if (!receiver.is(holder_reg)) {
|
| - ASSERT(scratch1.is(holder_reg));
|
| - __ Push(receiver, holder_reg);
|
| - __ lw(scratch3,
|
| - FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
|
| - __ Push(scratch3, scratch2, name_reg);
|
| - } else {
|
| - __ push(receiver);
|
| - __ lw(scratch3,
|
| - FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
|
| - __ Push(holder_reg, scratch3, scratch2, name_reg);
|
| - }
|
|
|
| + __ Push(receiver, holder_reg);
|
| + __ lw(scratch3,
|
| + FieldMemOperand(scratch2, AccessorInfo::kDataOffset));
|
| + __ li(scratch1, Operand(ExternalReference::isolate_address()));
|
| + __ Push(scratch3, scratch1, scratch2, name_reg);
|
| +
|
| ExternalReference ref =
|
| ExternalReference(IC_Utility(IC::kLoadCallbackProperty),
|
| masm()->isolate());
|
| - __ TailCallExternalReference(ref, 5, 1);
|
| + __ TailCallExternalReference(ref, 6, 1);
|
| }
|
| } else { // !compile_followup_inline
|
| // Call the runtime system to load the interceptor.
|
| @@ -1372,7 +1377,7 @@
|
|
|
| ExternalReference ref = ExternalReference(
|
| IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate());
|
| - __ TailCallExternalReference(ref, 5, 1);
|
| + __ TailCallExternalReference(ref, 6, 1);
|
| }
|
| }
|
|
|
| @@ -3373,6 +3378,45 @@
|
| }
|
|
|
|
|
| +static void GenerateSmiKeyCheck(MacroAssembler* masm,
|
| + Register key,
|
| + Register scratch0,
|
| + Register scratch1,
|
| + FPURegister double_scratch0,
|
| + Label* fail) {
|
| + if (CpuFeatures::IsSupported(FPU)) {
|
| + CpuFeatures::Scope scope(FPU);
|
| + Label key_ok;
|
| + // Check for smi or a smi inside a heap number. We convert the heap
|
| + // number and check if the conversion is exact and fits into the smi
|
| + // range.
|
| + __ JumpIfSmi(key, &key_ok);
|
| + __ CheckMap(key,
|
| + scratch0,
|
| + Heap::kHeapNumberMapRootIndex,
|
| + fail,
|
| + DONT_DO_SMI_CHECK);
|
| + __ ldc1(double_scratch0, FieldMemOperand(key, HeapNumber::kValueOffset));
|
| + __ EmitFPUTruncate(kRoundToZero,
|
| + double_scratch0,
|
| + double_scratch0,
|
| + scratch0,
|
| + scratch1,
|
| + kCheckForInexactConversion);
|
| +
|
| + __ Branch(fail, ne, scratch1, Operand(zero_reg));
|
| +
|
| + __ mfc1(scratch0, double_scratch0);
|
| + __ SmiTagCheckOverflow(key, scratch0, scratch1);
|
| + __ BranchOnOverflow(fail, scratch1);
|
| + __ bind(&key_ok);
|
| + } else {
|
| + // Check that the key is a smi.
|
| + __ JumpIfNotSmi(key, fail);
|
| + }
|
| +}
|
| +
|
| +
|
| void KeyedLoadStubCompiler::GenerateLoadExternalArray(
|
| MacroAssembler* masm,
|
| ElementsKind elements_kind) {
|
| @@ -3389,8 +3433,8 @@
|
| // This stub is meant to be tail-jumped to, the receiver must already
|
| // have been verified by the caller to not be a smi.
|
|
|
| - // Check that the key is a smi.
|
| - __ JumpIfNotSmi(key, &miss_force_generic);
|
| + // Check that the key is a smi or a heap number convertible to a smi.
|
| + GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic);
|
|
|
| __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| // a3: elements array
|
| @@ -3728,8 +3772,8 @@
|
| // This stub is meant to be tail-jumped to, the receiver must already
|
| // have been verified by the caller to not be a smi.
|
|
|
| - // Check that the key is a smi.
|
| - __ JumpIfNotSmi(key, &miss_force_generic);
|
| + // Check that the key is a smi or a heap number convertible to a smi.
|
| + GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic);
|
|
|
| __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
|
|
| @@ -4108,9 +4152,8 @@
|
| // This stub is meant to be tail-jumped to, the receiver must already
|
| // have been verified by the caller to not be a smi.
|
|
|
| - // Check that the key is a smi.
|
| - __ JumpIfNotSmi(a0, &miss_force_generic, at, USE_DELAY_SLOT);
|
| - // The delay slot can be safely used here, a1 is an object pointer.
|
| + // Check that the key is a smi or a heap number convertible to a smi.
|
| + GenerateSmiKeyCheck(masm, a0, t0, t1, f2, &miss_force_generic);
|
|
|
| // Get the elements array.
|
| __ lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset));
|
| @@ -4160,8 +4203,8 @@
|
| // This stub is meant to be tail-jumped to, the receiver must already
|
| // have been verified by the caller to not be a smi.
|
|
|
| - // Check that the key is a smi.
|
| - __ JumpIfNotSmi(key_reg, &miss_force_generic);
|
| + // Check that the key is a smi or a heap number convertible to a smi.
|
| + GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic);
|
|
|
| // Get the elements array.
|
| __ lw(elements_reg,
|
| @@ -4235,8 +4278,8 @@
|
| // This stub is meant to be tail-jumped to, the receiver must already
|
| // have been verified by the caller to not be a smi.
|
|
|
| - // Check that the key is a smi.
|
| - __ JumpIfNotSmi(key_reg, &miss_force_generic);
|
| + // Check that the key is a smi or a heap number convertible to a smi.
|
| + GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic);
|
|
|
| if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
|
| __ JumpIfNotSmi(value_reg, &transition_elements_kind);
|
| @@ -4402,8 +4445,10 @@
|
|
|
| // This stub is meant to be tail-jumped to, the receiver must already
|
| // have been verified by the caller to not be a smi.
|
| - __ JumpIfNotSmi(key_reg, &miss_force_generic);
|
|
|
| + // Check that the key is a smi or a heap number convertible to a smi.
|
| + GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic);
|
| +
|
| __ lw(elements_reg,
|
| FieldMemOperand(receiver_reg, JSObject::kElementsOffset));
|
|
|
|
|