diff options
Diffstat (limited to 'deps/v8/src/mips/stub-cache-mips.cc')
-rw-r--r-- | deps/v8/src/mips/stub-cache-mips.cc | 268 |
1 files changed, 183 insertions, 85 deletions
diff --git a/deps/v8/src/mips/stub-cache-mips.cc b/deps/v8/src/mips/stub-cache-mips.cc index 967ce4a605..391f8e072b 100644 --- a/deps/v8/src/mips/stub-cache-mips.cc +++ b/deps/v8/src/mips/stub-cache-mips.cc @@ -270,11 +270,12 @@ void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, int index, Register prototype) { // Load the global or builtins object from the current context. - __ lw(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); - // Load the global context from the global or builtins object. __ lw(prototype, - FieldMemOperand(prototype, GlobalObject::kGlobalContextOffset)); - // Load the function from the global context. + MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); + // Load the native context from the global or builtins object. + __ lw(prototype, + FieldMemOperand(prototype, GlobalObject::kNativeContextOffset)); + // Load the function from the native context. __ lw(prototype, MemOperand(prototype, Context::SlotOffset(index))); // Load the initial map. The global functions all have initial maps. __ lw(prototype, @@ -291,13 +292,14 @@ void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( Label* miss) { Isolate* isolate = masm->isolate(); // Check we're still in the same context. - __ lw(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); + __ lw(prototype, + MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); ASSERT(!prototype.is(at)); - __ li(at, isolate->global()); + __ li(at, isolate->global_object()); __ Branch(miss, ne, prototype, Operand(at)); // Get the global function with the given index. Handle<JSFunction> function( - JSFunction::cast(isolate->global_context()->get(index))); + JSFunction::cast(isolate->native_context()->get(index))); // Load its initial map. The global functions all have initial maps. __ li(prototype, Handle<Map>(function->initial_map())); // Load the prototype from the initial map. @@ -1234,6 +1236,44 @@ void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, } +void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, + Register name_reg, + Register scratch1, + Register scratch2, + Register scratch3, + Handle<AccessorInfo> callback, + Handle<String> name, + Label* miss) { + ASSERT(!receiver.is(scratch1)); + ASSERT(!receiver.is(scratch2)); + ASSERT(!receiver.is(scratch3)); + + // Load the properties dictionary. + Register dictionary = scratch1; + __ lw(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); + + // Probe the dictionary. + Label probe_done; + StringDictionaryLookupStub::GeneratePositiveLookup(masm(), + miss, + &probe_done, + dictionary, + name_reg, + scratch2, + scratch3); + __ bind(&probe_done); + + // If probing finds an entry in the dictionary, scratch3 contains the + // pointer into the dictionary. Check that the value is the callback. + Register pointer = scratch3; + const int kElementsStartOffset = StringDictionary::kHeaderSize + + StringDictionary::kElementsStartIndex * kPointerSize; + const int kValueOffset = kElementsStartOffset + kPointerSize; + __ lw(scratch2, FieldMemOperand(pointer, kValueOffset)); + __ Branch(miss, ne, scratch2, Operand(callback)); +} + + void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, Handle<JSObject> holder, Register receiver, @@ -1241,6 +1281,7 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, Register scratch1, Register scratch2, Register scratch3, + Register scratch4, Handle<AccessorInfo> callback, Handle<String> name, Label* miss) { @@ -1251,6 +1292,11 @@ void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, Register reg = CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, name, miss); + if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { + GenerateDictionaryLoadCallback( + reg, name_reg, scratch2, scratch3, scratch4, callback, name, miss); + } + // Build AccessorInfo::args_ list on the stack and push property name below // the exit frame to make GC aware of them and store pointers to them. __ push(receiver); @@ -1318,7 +1364,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, // later. bool compile_followup_inline = false; if (lookup->IsFound() && lookup->IsCacheable()) { - if (lookup->type() == FIELD) { + if (lookup->IsField()) { compile_followup_inline = true; } else if (lookup->type() == CALLBACKS && lookup->GetCallbackObject()->IsAccessorInfo()) { @@ -1391,7 +1437,7 @@ void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, miss); } - if (lookup->type() == FIELD) { + if (lookup->IsField()) { // We found FIELD property in prototype chain of interceptor's holder. // Retrieve a field from field's holder. GenerateFastPropertyLoad(masm(), v0, holder_reg, @@ -1531,7 +1577,7 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, GenerateMissBranch(); // Return the generated code. - return GetCode(FIELD, name); + return GetCode(Code::FIELD, name); } @@ -2078,7 +2124,7 @@ Handle<Code> CallStubCompiler::CompileStringFromCharCodeCall( GenerateMissBranch(); // Return the generated code. - return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name); + return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); } @@ -2212,7 +2258,7 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall( GenerateMissBranch(); // Return the generated code. - return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name); + return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); } @@ -2313,7 +2359,7 @@ Handle<Code> CallStubCompiler::CompileMathAbsCall( GenerateMissBranch(); // Return the generated code. - return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name); + return cell.is_null() ? GetCode(function) : GetCode(Code::NORMAL, name); } @@ -2534,7 +2580,7 @@ Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, GenerateMissBranch(); // Return the generated code. - return GetCode(INTERCEPTOR, name); + return GetCode(Code::INTERCEPTOR, name); } @@ -2593,7 +2639,7 @@ Handle<Code> CallStubCompiler::CompileCallGlobal( GenerateMissBranch(); // Return the generated code. - return GetCode(NORMAL, name); + return GetCode(Code::NORMAL, name); } @@ -2623,14 +2669,17 @@ Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, __ Jump(ic, RelocInfo::CODE_TARGET); // Return the generated code. - return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); + return GetCode(transition.is_null() + ? Code::FIELD + : Code::MAP_TRANSITION, name); } Handle<Code> StoreStubCompiler::CompileStoreCallback( - Handle<JSObject> object, - Handle<AccessorInfo> callback, - Handle<String> name) { + Handle<String> name, + Handle<JSObject> receiver, + Handle<JSObject> holder, + Handle<AccessorInfo> callback) { // ----------- S t a t e ------------- // -- a0 : value // -- a1 : receiver @@ -2638,19 +2687,13 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback( // -- ra : return address // ----------------------------------- Label miss; - - // Check that the map of the object hasn't changed. - __ CheckMap(a1, a3, Handle<Map>(object->map()), &miss, - DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); - - // Perform global security token check if needed. - if (object->IsJSGlobalProxy()) { - __ CheckAccessGlobalProxy(a1, a3, &miss); - } + // Check that the maps haven't changed. + __ JumpIfSmi(a1, &miss, a3); + CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss); // Stub never generated for non-global objects that require access // checks. - ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); + ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); __ push(a1); // Receiver. __ li(a3, Operand(callback)); // Callback info. @@ -2668,38 +2711,41 @@ Handle<Code> StoreStubCompiler::CompileStoreCallback( __ Jump(ic, RelocInfo::CODE_TARGET); // Return the generated code. - return GetCode(CALLBACKS, name); + return GetCode(Code::CALLBACKS, name); } -Handle<Code> StoreStubCompiler::CompileStoreViaSetter( - Handle<JSObject> receiver, - Handle<JSFunction> setter, - Handle<String> name) { +#undef __ +#define __ ACCESS_MASM(masm) + + +void StoreStubCompiler::GenerateStoreViaSetter( + MacroAssembler* masm, + Handle<JSFunction> setter) { // ----------- S t a t e ------------- // -- a0 : value // -- a1 : receiver // -- a2 : name // -- ra : return address // ----------------------------------- - Label miss; - - // Check that the map of the object hasn't changed. - __ CheckMap(a1, a3, Handle<Map>(receiver->map()), &miss, DO_SMI_CHECK, - ALLOW_ELEMENT_TRANSITION_MAPS); - { - FrameScope scope(masm(), StackFrame::INTERNAL); + FrameScope scope(masm, StackFrame::INTERNAL); // Save value register, so we can restore it later. __ push(a0); - // Call the JavaScript getter with the receiver and the value on the stack. - __ push(a1); - __ push(a0); - ParameterCount actual(1); - __ InvokeFunction(setter, actual, CALL_FUNCTION, NullCallWrapper(), - CALL_AS_METHOD); + if (!setter.is_null()) { + // Call the JavaScript setter with receiver and value on the stack. + __ push(a1); + __ push(a0); + ParameterCount actual(1); + __ InvokeFunction(setter, actual, CALL_FUNCTION, NullCallWrapper(), + CALL_AS_METHOD); + } else { + // If we generate a global code snippet for deoptimization only, remember + // the place to continue after deoptimization. + masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); + } // We have to return the passed value, not the return value of the setter. __ pop(v0); @@ -2708,13 +2754,38 @@ Handle<Code> StoreStubCompiler::CompileStoreViaSetter( __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); } __ Ret(); +} + + +#undef __ +#define __ ACCESS_MASM(masm()) + + +Handle<Code> StoreStubCompiler::CompileStoreViaSetter( + Handle<String> name, + Handle<JSObject> receiver, + Handle<JSObject> holder, + Handle<JSFunction> setter) { + // ----------- S t a t e ------------- + // -- a0 : value + // -- a1 : receiver + // -- a2 : name + // -- ra : return address + // ----------------------------------- + Label miss; + + // Check that the maps haven't changed. + __ JumpIfSmi(a1, &miss); + CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss); + + GenerateStoreViaSetter(masm(), setter); __ bind(&miss); Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); __ Jump(ic, RelocInfo::CODE_TARGET); // Return the generated code. - return GetCode(CALLBACKS, name); + return GetCode(Code::CALLBACKS, name); } @@ -2759,7 +2830,7 @@ Handle<Code> StoreStubCompiler::CompileStoreInterceptor( __ Jump(ic, RelocInfo::CODE_TARGET); // Return the generated code. - return GetCode(INTERCEPTOR, name); + return GetCode(Code::INTERCEPTOR, name); } @@ -2804,7 +2875,7 @@ Handle<Code> StoreStubCompiler::CompileStoreGlobal( __ Jump(ic, RelocInfo::CODE_TARGET); // Return the generated code. - return GetCode(NORMAL, name); + return GetCode(Code::NORMAL, name); } @@ -2838,7 +2909,7 @@ Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name, GenerateLoadMiss(masm(), Code::LOAD_IC); // Return the generated code. - return GetCode(NONEXISTENT, factory()->empty_string()); + return GetCode(Code::NONEXISTENT, factory()->empty_string()); } @@ -2860,7 +2931,7 @@ Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, GenerateLoadMiss(masm(), Code::LOAD_IC); // Return the generated code. - return GetCode(FIELD, name); + return GetCode(Code::FIELD, name); } @@ -2875,16 +2946,53 @@ Handle<Code> LoadStubCompiler::CompileLoadCallback( // -- ra : return address // ----------------------------------- Label miss; - GenerateLoadCallback(object, holder, a0, a2, a3, a1, t0, callback, name, + GenerateLoadCallback(object, holder, a0, a2, a3, a1, t0, t1, callback, name, &miss); __ bind(&miss); GenerateLoadMiss(masm(), Code::LOAD_IC); // Return the generated code. - return GetCode(CALLBACKS, name); + return GetCode(Code::CALLBACKS, name); +} + + +#undef __ +#define __ ACCESS_MASM(masm) + + +void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, + Handle<JSFunction> getter) { + // ----------- S t a t e ------------- + // -- a0 : receiver + // -- a2 : name + // -- ra : return address + // ----------------------------------- + { + FrameScope scope(masm, StackFrame::INTERNAL); + + if (!getter.is_null()) { + // Call the JavaScript getter with the receiver on the stack. + __ push(a0); + ParameterCount actual(0); + __ InvokeFunction(getter, actual, CALL_FUNCTION, NullCallWrapper(), + CALL_AS_METHOD); + } else { + // If we generate a global code snippet for deoptimization only, remember + // the place to continue after deoptimization. + masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); + } + + // Restore context register. + __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); + } + __ Ret(); } +#undef __ +#define __ ACCESS_MASM(masm()) + + Handle<Code> LoadStubCompiler::CompileLoadViaGetter( Handle<String> name, Handle<JSObject> receiver, @@ -2901,25 +3009,13 @@ Handle<Code> LoadStubCompiler::CompileLoadViaGetter( __ JumpIfSmi(a0, &miss); CheckPrototypes(receiver, a0, holder, a3, t0, a1, name, &miss); - { - FrameScope scope(masm(), StackFrame::INTERNAL); - - // Call the JavaScript getter with the receiver on the stack. - __ push(a0); - ParameterCount actual(0); - __ InvokeFunction(getter, actual, CALL_FUNCTION, NullCallWrapper(), - CALL_AS_METHOD); - - // Restore context register. - __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - } - __ Ret(); + GenerateLoadViaGetter(masm(), getter); __ bind(&miss); GenerateLoadMiss(masm(), Code::LOAD_IC); // Return the generated code. - return GetCode(CALLBACKS, name); + return GetCode(Code::CALLBACKS, name); } @@ -2939,7 +3035,7 @@ Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, GenerateLoadMiss(masm(), Code::LOAD_IC); // Return the generated code. - return GetCode(CONSTANT_FUNCTION, name); + return GetCode(Code::CONSTANT_FUNCTION, name); } @@ -2962,7 +3058,7 @@ Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> object, GenerateLoadMiss(masm(), Code::LOAD_IC); // Return the generated code. - return GetCode(INTERCEPTOR, name); + return GetCode(Code::INTERCEPTOR, name); } @@ -3003,7 +3099,7 @@ Handle<Code> LoadStubCompiler::CompileLoadGlobal( GenerateLoadMiss(masm(), Code::LOAD_IC); // Return the generated code. - return GetCode(NORMAL, name); + return GetCode(Code::NORMAL, name); } @@ -3025,7 +3121,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, __ bind(&miss); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); - return GetCode(FIELD, name); + return GetCode(Code::FIELD, name); } @@ -3044,12 +3140,12 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback( // Check the key is the cached one. __ Branch(&miss, ne, a0, Operand(name)); - GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, t0, callback, name, - &miss); + GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, t0, t1, callback, + name, &miss); __ bind(&miss); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); - return GetCode(CALLBACKS, name); + return GetCode(Code::CALLBACKS, name); } @@ -3073,7 +3169,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); // Return the generated code. - return GetCode(CONSTANT_FUNCTION, name); + return GetCode(Code::CONSTANT_FUNCTION, name); } @@ -3098,7 +3194,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor( __ bind(&miss); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); - return GetCode(INTERCEPTOR, name); + return GetCode(Code::INTERCEPTOR, name); } @@ -3118,7 +3214,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( __ bind(&miss); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); - return GetCode(CALLBACKS, name); + return GetCode(Code::CALLBACKS, name); } @@ -3143,7 +3239,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); - return GetCode(CALLBACKS, name); + return GetCode(Code::CALLBACKS, name); } @@ -3167,7 +3263,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( __ DecrementCounter(counters->keyed_load_function_prototype(), 1, a2, a3); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); - return GetCode(CALLBACKS, name); + return GetCode(Code::CALLBACKS, name); } @@ -3187,7 +3283,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( __ Jump(ic, RelocInfo::CODE_TARGET); // Return the generated code. - return GetCode(NORMAL, factory()->empty_string()); + return GetCode(Code::NORMAL, factory()->empty_string()); } @@ -3214,7 +3310,7 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( __ Jump(miss_ic, RelocInfo::CODE_TARGET); // Return the generated code. - return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); + return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC); } @@ -3253,7 +3349,9 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, __ Jump(ic, RelocInfo::CODE_TARGET); // Return the generated code. - return GetCode(transition.is_null() ? FIELD : MAP_TRANSITION, name); + return GetCode(transition.is_null() + ? Code::FIELD + : Code::MAP_TRANSITION, name); } @@ -3277,7 +3375,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( __ Jump(ic, RelocInfo::CODE_TARGET); // Return the generated code. - return GetCode(NORMAL, factory()->empty_string()); + return GetCode(Code::NORMAL, factory()->empty_string()); } @@ -3315,7 +3413,7 @@ Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( __ Jump(miss_ic, RelocInfo::CODE_TARGET); // Return the generated code. - return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); + return GetCode(Code::NORMAL, factory()->empty_string(), MEGAMORPHIC); } |