| Index: src/mips/stub-cache-mips.cc
|
| diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
|
| index 166540d5768619755155112acaf229fa0d16260d..e2ab36d4859b23fe28d67a50061cae8acbec63e1 100644
|
| --- a/src/mips/stub-cache-mips.cc
|
| +++ b/src/mips/stub-cache-mips.cc
|
| @@ -297,10 +297,10 @@ void NamedStoreHandlerCompiler::GenerateNegativeHolderLookup(
|
| // After executing generated code, the receiver_reg and name_reg
|
| // may be clobbered.
|
| void NamedStoreHandlerCompiler::GenerateStoreTransition(
|
| - MacroAssembler* masm, Handle<JSObject> object, LookupResult* lookup,
|
| - Handle<Map> transition, Handle<Name> name, Register receiver_reg,
|
| - Register storage_reg, Register value_reg, Register scratch1,
|
| - Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
|
| + MacroAssembler* masm, LookupResult* lookup, Handle<Map> transition,
|
| + Handle<Name> name, Register receiver_reg, Register storage_reg,
|
| + Register value_reg, Register scratch1, Register scratch2, Register scratch3,
|
| + Label* miss_label, Label* slow) {
|
| // a0 : value.
|
| Label exit;
|
|
|
| @@ -357,13 +357,12 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
|
| __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
|
| }
|
|
|
| - // Stub never generated for non-global objects that require access
|
| - // checks.
|
| - ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
|
| + // Stub never generated for objects that require access checks.
|
| + ASSERT(!transition->is_access_check_needed());
|
|
|
| // Perform map transition for the receiver if necessary.
|
| if (details.type() == FIELD &&
|
| - object->map()->unused_property_fields() == 0) {
|
| + Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
|
| // The properties must be extended before we can store the value.
|
| // We jump to a runtime call that extends the properties array.
|
| __ push(receiver_reg);
|
| @@ -403,14 +402,14 @@ void NamedStoreHandlerCompiler::GenerateStoreTransition(
|
| // Adjust for the number of properties stored in the object. Even in the
|
| // face of a transition we can use the old map here because the size of the
|
| // object and the number of in-object properties is not going to change.
|
| - index -= object->map()->inobject_properties();
|
| + index -= transition->inobject_properties();
|
|
|
| // TODO(verwaest): Share this code as a code stub.
|
| SmiCheck smi_check = representation.IsTagged()
|
| ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
|
| if (index < 0) {
|
| // Set the property straight into the object.
|
| - int offset = object->map()->instance_size() + (index * kPointerSize);
|
| + int offset = transition->instance_size() + (index * kPointerSize);
|
| if (representation.IsDouble()) {
|
| __ sw(storage_reg, FieldMemOperand(receiver_reg, offset));
|
| } else {
|
| @@ -725,10 +724,10 @@ void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
|
|
|
|
|
| Register PropertyHandlerCompiler::CheckPrototypes(
|
| - Handle<HeapType> type, Register object_reg, Handle<JSObject> holder,
|
| - Register holder_reg, Register scratch1, Register scratch2,
|
| - Handle<Name> name, Label* miss, PrototypeCheckType check) {
|
| - Handle<Map> receiver_map(IC::TypeToMap(*type, isolate()));
|
| + Register object_reg, Register holder_reg, Register scratch1,
|
| + Register scratch2, Handle<Name> name, Label* miss,
|
| + PrototypeCheckType check) {
|
| + Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
|
|
|
| // Make sure there's no overlap between holder and object registers.
|
| ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
|
| @@ -740,12 +739,12 @@ Register PropertyHandlerCompiler::CheckPrototypes(
|
| int depth = 0;
|
|
|
| Handle<JSObject> current = Handle<JSObject>::null();
|
| - if (type->IsConstant()) {
|
| - current = Handle<JSObject>::cast(type->AsConstant()->Value());
|
| + if (type()->IsConstant()) {
|
| + current = Handle<JSObject>::cast(type()->AsConstant()->Value());
|
| }
|
| Handle<JSObject> prototype = Handle<JSObject>::null();
|
| Handle<Map> current_map = receiver_map;
|
| - Handle<Map> holder_map(holder->map());
|
| + Handle<Map> holder_map(holder()->map());
|
| // Traverse the prototype chain and check the maps in the prototype chain for
|
| // fast and global objects or do negative lookup for normal objects.
|
| while (!current_map.is_identical_to(holder_map)) {
|
| @@ -856,16 +855,15 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
|
| }
|
|
|
|
|
| -Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type,
|
| - Register object_reg,
|
| - Handle<JSObject> holder,
|
| +Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
|
| Handle<Name> name,
|
| Handle<Object> callback) {
|
| Label miss;
|
|
|
| - Register reg = FrontendHeader(type, object_reg, holder, name, &miss);
|
| + Register reg = FrontendHeader(object_reg, name, &miss);
|
|
|
| - if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
|
| + if (!holder()->HasFastProperties()) {
|
| + ASSERT(!holder()->IsGlobalObject());
|
| ASSERT(!reg.is(scratch2()));
|
| ASSERT(!reg.is(scratch3()));
|
| ASSERT(!reg.is(scratch4()));
|
| @@ -901,8 +899,7 @@ Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type,
|
|
|
|
|
| void NamedLoadHandlerCompiler::GenerateLoadField(
|
| - Register reg, Handle<JSObject> holder, FieldIndex field,
|
| - Representation representation) {
|
| + Register reg, FieldIndex field, Representation representation) {
|
| if (!reg.is(receiver())) __ mov(receiver(), reg);
|
| LoadFieldStub stub(isolate(), field);
|
| GenerateTailCall(masm(), stub.GetCode());
|
| @@ -965,12 +962,11 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback(
|
| }
|
|
|
|
|
| -void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
|
| - Register holder_reg, Handle<Object> object,
|
| - Handle<JSObject> interceptor_holder, LookupResult* lookup,
|
| - Handle<Name> name) {
|
| - ASSERT(interceptor_holder->HasNamedInterceptor());
|
| - ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
|
| +void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg,
|
| + LookupResult* lookup,
|
| + Handle<Name> name) {
|
| + ASSERT(holder()->HasNamedInterceptor());
|
| + ASSERT(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
|
|
|
| // So far the most popular follow ups for interceptor loads are FIELD
|
| // and CALLBACKS, so inline only them, other cases may be added
|
| @@ -981,10 +977,12 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
|
| compile_followup_inline = true;
|
| } else if (lookup->type() == CALLBACKS &&
|
| lookup->GetCallbackObject()->IsExecutableAccessorInfo()) {
|
| - ExecutableAccessorInfo* callback =
|
| - ExecutableAccessorInfo::cast(lookup->GetCallbackObject());
|
| - compile_followup_inline = callback->getter() != NULL &&
|
| - callback->IsCompatibleReceiver(*object);
|
| + Handle<ExecutableAccessorInfo> callback(
|
| + ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
|
| + compile_followup_inline =
|
| + callback->getter() != NULL &&
|
| + ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), callback,
|
| + type());
|
| }
|
| }
|
|
|
| @@ -998,7 +996,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
|
| // the holder and it is needed should the interceptor return without any
|
| // result. The CALLBACKS case needs the receiver to be passed into C++ code,
|
| // the FIELD case might cause a miss during the prototype check.
|
| - bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder();
|
| + bool must_perfrom_prototype_check = *holder() != lookup->holder();
|
| bool must_preserve_receiver_reg = !receiver().is(holder_reg) &&
|
| (lookup->type() == CALLBACKS || must_perfrom_prototype_check);
|
|
|
| @@ -1015,7 +1013,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
|
| // interceptor's holder has been compiled before (see a caller
|
| // of this method).
|
| CompileCallLoadPropertyWithInterceptor(
|
| - masm(), receiver(), holder_reg, this->name(), interceptor_holder,
|
| + masm(), receiver(), holder_reg, this->name(), holder(),
|
| IC::kLoadPropertyWithInterceptorOnly);
|
|
|
| // Check if interceptor provided a value for property. If it's
|
| @@ -1034,12 +1032,12 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
|
| }
|
| // Leave the internal frame.
|
| }
|
| - GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup);
|
| + GenerateLoadPostInterceptor(holder_reg, name, lookup);
|
| } else { // !compile_followup_inline
|
| // Call the runtime system to load the interceptor.
|
| // Check that the maps haven't changed.
|
| - PushInterceptorArguments(masm(), receiver(), holder_reg,
|
| - this->name(), interceptor_holder);
|
| + PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
|
| + holder());
|
|
|
| ExternalReference ref = ExternalReference(
|
| IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
|
| @@ -1050,14 +1048,9 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
|
|
|
|
|
| Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
|
| - Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
|
| + Handle<JSObject> object, Handle<Name> name,
|
| Handle<ExecutableAccessorInfo> callback) {
|
| - Register holder_reg =
|
| - Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
|
| -
|
| - // Stub never generated for non-global objects that require access
|
| - // checks.
|
| - ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
|
| + Register holder_reg = Frontend(receiver(), name);
|
|
|
| __ Push(receiver(), holder_reg); // Receiver.
|
| __ li(at, Operand(callback)); // Callback info.
|
| @@ -1124,7 +1117,7 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
|
|
|
|
|
| Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
|
| - Handle<JSObject> object, Handle<Name> name) {
|
| + Handle<Name> name) {
|
| __ Push(receiver(), this->name(), value());
|
|
|
| // Do tail-call to the runtime system.
|
| @@ -1138,8 +1131,8 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
|
|
|
|
|
| Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
|
| - Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) {
|
| - NonexistentFrontend(type, last, name);
|
| + Handle<Name> name) {
|
| + NonexistentFrontend(name);
|
|
|
| // Return undefined if maps of the full prototype chain is still the same.
|
| __ LoadRoot(v0, Heap::kUndefinedValueRootIndex);
|
| @@ -1163,21 +1156,12 @@ Register* PropertyAccessCompiler::store_calling_convention() {
|
| // receiver, name, scratch1, scratch2, scratch3.
|
| Register receiver = StoreIC::ReceiverRegister();
|
| Register name = StoreIC::NameRegister();
|
| + ASSERT(a3.is(KeyedStoreIC::MapRegister()));
|
| static Register registers[] = { receiver, name, a3, t0, t1 };
|
| return registers;
|
| }
|
|
|
|
|
| -Register* PropertyAccessCompiler::keyed_store_calling_convention() {
|
| - // receiver, name, scratch1/map, scratch2, scratch3.
|
| - Register receiver = KeyedStoreIC::ReceiverRegister();
|
| - Register name = KeyedStoreIC::NameRegister();
|
| - Register map = KeyedStoreIC::MapRegister();
|
| - static Register registers[] = { receiver, name, map, t0, t1 };
|
| - return registers;
|
| -}
|
| -
|
| -
|
| Register NamedStoreHandlerCompiler::value() { return StoreIC::ValueRegister(); }
|
|
|
|
|
| @@ -1226,26 +1210,26 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
|
|
|
|
|
| Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
|
| - Handle<HeapType> type, Handle<GlobalObject> global,
|
| Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
|
| Label miss;
|
|
|
| - FrontendHeader(type, receiver(), global, name, &miss);
|
| + FrontendHeader(receiver(), name, &miss);
|
|
|
| // Get the value from the cell.
|
| - __ li(a3, Operand(cell));
|
| - __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset));
|
| + Register result = StoreIC::ValueRegister();
|
| + __ li(result, Operand(cell));
|
| + __ lw(result, FieldMemOperand(result, Cell::kValueOffset));
|
|
|
| // Check for deleted property if property can actually be deleted.
|
| if (!is_dont_delete) {
|
| __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
|
| - __ Branch(&miss, eq, t0, Operand(at));
|
| + __ Branch(&miss, eq, result, Operand(at));
|
| }
|
|
|
| Counters* counters = isolate()->counters();
|
| __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
|
| __ Ret(USE_DELAY_SLOT);
|
| - __ mov(v0, t0);
|
| + __ mov(v0, result);
|
|
|
| FrontendFooter(name, &miss);
|
|
|
|
|