Encapsulate type in the PropertyHandlerCompiler
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 30 Jul 2014 10:09:10 +0000 (10:09 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 30 Jul 2014 10:09:10 +0000 (10:09 +0000)
BUG=
R=ishell@chromium.org

Review URL: https://codereview.chromium.org/426633002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22700 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/stub-cache-arm.cc
src/arm64/stub-cache-arm64.cc
src/ia32/stub-cache-ia32.cc
src/ic.cc
src/objects-inl.h
src/objects.cc
src/objects.h
src/stub-cache.cc
src/stub-cache.h
src/x64/stub-cache-x64.cc

index 391d85a519abd3731b2fe8df166d8a3551ffbbc1..ea1ed1bc76564f90f007a2cb9a0673a33a7b663a 100644 (file)
@@ -733,10 +733,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, 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()));
 
   // Make sure there's no overlap between holder and object registers.
   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
@@ -748,8 +748,8 @@ 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;
@@ -864,14 +864,13 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
 }
 
 
-Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type,
-                                                    Register object_reg,
+Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
                                                     Handle<JSObject> holder,
                                                     Handle<Name> name,
                                                     Handle<Object> callback) {
   Label miss;
 
-  Register reg = FrontendHeader(type, object_reg, holder, name, &miss);
+  Register reg = FrontendHeader(object_reg, holder, name, &miss);
 
   if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
     ASSERT(!reg.is(scratch2()));
@@ -972,9 +971,8 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback(
 
 
 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
-    Register holder_reg, Handle<Object> object,
-    Handle<JSObject> interceptor_holder, LookupResult* lookup,
-    Handle<Name> name) {
+    Register holder_reg, Handle<JSObject> interceptor_holder,
+    LookupResult* lookup, Handle<Name> name) {
   ASSERT(interceptor_holder->HasNamedInterceptor());
   ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
 
@@ -987,10 +985,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());
     }
   }
 
@@ -1061,8 +1061,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg =
-      Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
+  Register holder_reg = Frontend(receiver(), holder, name);
 
   // Stub never generated for non-global objects that require access checks.
   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
@@ -1147,8 +1146,8 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
-    Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) {
-  NonexistentFrontend(type, last, name);
+    Handle<JSObject> last, Handle<Name> name) {
+  NonexistentFrontend(last, name);
 
   // Return undefined if maps of the full prototype chain are still the
   // same and no global property with this name contains a value.
@@ -1236,25 +1235,25 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
-    Handle<HeapType> type, Handle<GlobalObject> global,
-    Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
+    Handle<GlobalObject> global, Handle<PropertyCell> cell, Handle<Name> name,
+    bool is_dont_delete) {
   Label miss;
-  FrontendHeader(type, receiver(), global, name, &miss);
+  FrontendHeader(receiver(), global, name, &miss);
 
   // Get the value from the cell.
-  __ mov(r3, Operand(cell));
-  __ ldr(r4, FieldMemOperand(r3, Cell::kValueOffset));
+  Register result = StoreIC::ValueRegister();
+  __ mov(result, Operand(cell));
+  __ ldr(result, FieldMemOperand(result, Cell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
   if (!is_dont_delete) {
     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
-    __ cmp(r4, ip);
+    __ cmp(result, ip);
     __ b(eq, &miss);
   }
 
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
-  __ mov(r0, r4);
   __ Ret();
 
   FrontendFooter(name, &miss);
index c1ae0eb51af391868dbfd658d8c422131570734d..20431d6c09c2b1c86ccdc5a5c42e4314438fc316 100644 (file)
@@ -682,10 +682,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, 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()));
 
   // object_reg and holder_reg registers can alias.
   ASSERT(!AreAliased(object_reg, scratch1, scratch2));
@@ -696,8 +696,8 @@ 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;
@@ -817,14 +817,13 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
 }
 
 
-Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type,
-                                                    Register object_reg,
+Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
                                                     Handle<JSObject> holder,
                                                     Handle<Name> name,
                                                     Handle<Object> callback) {
   Label miss;
 
-  Register reg = FrontendHeader(type, object_reg, holder, name, &miss);
+  Register reg = FrontendHeader(object_reg, holder, name, &miss);
   // FrontendHeader can return its result into scratch1() so do not
   // use it.
   Register scratch2 = this->scratch2();
@@ -934,9 +933,8 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback(
 
 
 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
-    Register holder_reg, Handle<Object> object,
-    Handle<JSObject> interceptor_holder, LookupResult* lookup,
-    Handle<Name> name) {
+    Register holder_reg, Handle<JSObject> interceptor_holder,
+    LookupResult* lookup, Handle<Name> name) {
   ASSERT(!AreAliased(receiver(), this->name(),
                      scratch1(), scratch2(), scratch3()));
   ASSERT(interceptor_holder->HasNamedInterceptor());
@@ -950,10 +948,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());
     }
   }
 
@@ -1024,8 +1024,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
   ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback");
-  Register holder_reg =
-      Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
+  Register holder_reg = Frontend(receiver(), holder, name);
 
   // Stub never generated for non-global objects that require access checks.
   ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
@@ -1116,8 +1115,8 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
-    Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) {
-  NonexistentFrontend(type, last, name);
+    Handle<JSObject> last, Handle<Name> name) {
+  NonexistentFrontend(last, name);
 
   // Return undefined if maps of the full prototype chain are still the
   // same and no global property with this name contains a value.
@@ -1206,23 +1205,23 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
-    Handle<HeapType> type, Handle<GlobalObject> global,
-    Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
+    Handle<GlobalObject> global, Handle<PropertyCell> cell, Handle<Name> name,
+    bool is_dont_delete) {
   Label miss;
-  FrontendHeader(type, receiver(), global, name, &miss);
+  FrontendHeader(receiver(), global, name, &miss);
 
   // Get the value from the cell.
-  __ Mov(x3, Operand(cell));
-  __ Ldr(x4, FieldMemOperand(x3, Cell::kValueOffset));
+  Register result = StoreIC::ValueRegister();
+  __ Mov(result, Operand(cell));
+  __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
   if (!is_dont_delete) {
-    __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss);
+    __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss);
   }
 
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3);
-  __ Mov(x0, x4);
   __ Ret();
 
   FrontendFooter(name, &miss);
index 8192ece896a39c34530444d7b08f767d5350d691..b5aaa123633a3cea0c703b21444a7a53d28718a0 100644 (file)
@@ -693,10 +693,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, 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()));
 
   // Make sure there's no overlap between holder and object registers.
   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
@@ -708,8 +708,8 @@ 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());
@@ -824,14 +824,13 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
 }
 
 
-Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type,
-                                                    Register object_reg,
+Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
                                                     Handle<JSObject> holder,
                                                     Handle<Name> name,
                                                     Handle<Object> callback) {
   Label miss;
 
-  Register reg = FrontendHeader(type, object_reg, holder, name, &miss);
+  Register reg = FrontendHeader(object_reg, holder, name, &miss);
 
   if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
     ASSERT(!reg.is(scratch2()));
@@ -944,9 +943,8 @@ void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
 
 
 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
-    Register holder_reg, Handle<Object> object,
-    Handle<JSObject> interceptor_holder, LookupResult* lookup,
-    Handle<Name> name) {
+    Register holder_reg, Handle<JSObject> interceptor_holder,
+    LookupResult* lookup, Handle<Name> name) {
   ASSERT(interceptor_holder->HasNamedInterceptor());
   ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
 
@@ -959,10 +957,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());
     }
   }
 
@@ -1044,8 +1044,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg =
-      Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
+  Register holder_reg = Frontend(receiver(), holder, name);
 
   __ pop(scratch1());  // remove the return address
   __ push(receiver());
@@ -1173,8 +1172,8 @@ Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
-    Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) {
-  NonexistentFrontend(type, last, name);
+    Handle<JSObject> last, Handle<Name> name) {
+  NonexistentFrontend(last, name);
 
   // Return undefined if maps of the full prototype chain are still the
   // same and no global property with this name contains a value.
@@ -1257,25 +1256,26 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
-    Handle<HeapType> type, Handle<GlobalObject> global,
-    Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
+    Handle<GlobalObject> global, Handle<PropertyCell> cell, Handle<Name> name,
+    bool is_dont_delete) {
   Label miss;
 
-  FrontendHeader(type, receiver(), global, name, &miss);
+  FrontendHeader(receiver(), global, name, &miss);
   // Get the value from the cell.
+  Register result = StoreIC::ValueRegister();
   if (masm()->serializer_enabled()) {
-    __ mov(eax, Immediate(cell));
-    __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset));
+    __ mov(result, Immediate(cell));
+    __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
   } else {
-    __ mov(eax, Operand::ForCell(cell));
+    __ mov(result, Operand::ForCell(cell));
   }
 
   // Check for deleted property if property can actually be deleted.
   if (!is_dont_delete) {
-    __ cmp(eax, factory()->the_hole_value());
+    __ cmp(result, factory()->the_hole_value());
     __ j(equal, &miss);
   } else if (FLAG_debug_code) {
-    __ cmp(eax, factory()->the_hole_value());
+    __ cmp(result, factory()->the_hole_value());
     __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
   }
 
index c11f58244e05b2299d61280f5fa0044d98a6c8ff..eb84fd14620367b835a5966327ace69f836918e2 100644 (file)
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -942,7 +942,7 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, Handle<Object> object,
   Handle<HeapType> type = receiver_type();
   Handle<JSObject> holder(lookup->holder());
   bool receiver_is_holder = object.is_identical_to(holder);
-  NamedLoadHandlerCompiler compiler(isolate(), cache_holder);
+  NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), cache_holder);
 
   switch (lookup->type()) {
     case FIELD: {
@@ -950,12 +950,12 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, Handle<Object> object,
       if (receiver_is_holder) {
         return SimpleFieldLoad(field);
       }
-      return compiler.CompileLoadField(
-          type, holder, name, field, lookup->representation());
+      return compiler.CompileLoadField(holder, name, field,
+                                       lookup->representation());
     }
     case CONSTANT: {
       Handle<Object> constant(lookup->GetConstant(), isolate());
-      return compiler.CompileLoadConstant(type, holder, name, constant);
+      return compiler.CompileLoadConstant(holder, name, constant);
     }
     case NORMAL:
       if (kind() != Code::LOAD_IC) break;
@@ -963,8 +963,8 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, Handle<Object> object,
         Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
         Handle<PropertyCell> cell(
             global->GetPropertyCell(lookup), isolate());
-        Handle<Code> code = compiler.CompileLoadGlobal(
-            type, global, cell, name, lookup->IsDontDelete());
+        Handle<Code> code = compiler.CompileLoadGlobal(global, cell, name,
+                                                       lookup->IsDontDelete());
         // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
         CacheHolderFlag flag;
         Handle<Map> stub_holder_map =
@@ -997,8 +997,11 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, Handle<Object> object,
         Handle<ExecutableAccessorInfo> info =
             Handle<ExecutableAccessorInfo>::cast(callback);
         if (v8::ToCData<Address>(info->getter()) == 0) break;
-        if (!info->IsCompatibleReceiver(*object)) break;
-        return compiler.CompileLoadCallback(type, holder, name, info);
+        if (!ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), info,
+                                                              type)) {
+          break;
+        }
+        return compiler.CompileLoadCallback(holder, name, info);
       } else if (callback->IsAccessorPair()) {
         Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(),
                               isolate());
@@ -1016,10 +1019,9 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, Handle<Object> object,
         CallOptimization call_optimization(function);
         if (call_optimization.is_simple_api_call() &&
             call_optimization.IsCompatibleReceiver(object, holder)) {
-          return compiler.CompileLoadCallback(
-              type, holder, name, call_optimization);
+          return compiler.CompileLoadCallback(holder, name, call_optimization);
         }
-        return compiler.CompileLoadViaGetter(type, holder, name, function);
+        return compiler.CompileLoadViaGetter(holder, name, function);
       }
       // TODO(dcarney): Handle correctly.
       ASSERT(callback->IsDeclaredAccessorInfo());
@@ -1027,7 +1029,7 @@ Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, Handle<Object> object,
     }
     case INTERCEPTOR:
       ASSERT(HasInterceptorGetter(*holder));
-      return compiler.CompileLoadInterceptor(type, holder, name);
+      return compiler.CompileLoadInterceptor(holder, name);
     default:
       break;
   }
@@ -1392,7 +1394,7 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
   Handle<JSObject> receiver = Handle<JSObject>::cast(object);
 
   Handle<JSObject> holder(lookup->holder());
-  NamedStoreHandlerCompiler compiler(isolate());
+  NamedStoreHandlerCompiler compiler(isolate(), receiver_type());
 
   if (lookup->IsTransition()) {
     // Explicitly pass in the receiver map since LookupForWrite may have
@@ -1438,7 +1440,10 @@ Handle<Code> StoreIC::CompileHandler(LookupResult* lookup,
               Handle<ExecutableAccessorInfo>::cast(callback);
           if (v8::ToCData<Address>(info->setter()) == 0) break;
           if (!holder->HasFastProperties()) break;
-          if (!info->IsCompatibleReceiver(*receiver)) break;
+          if (!ExecutableAccessorInfo::IsCompatibleReceiverType(
+                  isolate(), info, receiver_type())) {
+            break;
+          }
           return compiler.CompileStoreCallback(receiver, holder, name, info);
         } else if (callback->IsAccessorPair()) {
           Handle<Object> setter(
index 22bdfa381e93bbd0150ff72a1a5fb83b6545dbb8..e14c1af6db83bbb880df0768ed2c5fe726cf0a23 100644 (file)
@@ -6771,9 +6771,10 @@ void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
 
 
 bool AccessorInfo::IsCompatibleReceiver(Object* receiver) {
-  Object* function_template = expected_receiver_type();
-  if (!function_template->IsFunctionTemplateInfo()) return true;
-  return FunctionTemplateInfo::cast(function_template)->IsTemplateFor(receiver);
+  if (!HasExpectedReceiverType()) return true;
+  if (!receiver->IsJSObject()) return false;
+  return FunctionTemplateInfo::cast(expected_receiver_type())
+      ->IsTemplateFor(JSObject::cast(receiver)->map());
 }
 
 
index a846fba4164c9cf3647cbbd0297365cb8bbd03d2..79b2ffc150dcd79f1768270a3adc036304204215 100644 (file)
@@ -409,8 +409,8 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver,
   ASSERT(!structure->IsForeign());
   // api style callbacks.
   if (structure->IsAccessorInfo()) {
-    Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure);
-    if (!accessor_info->IsCompatibleReceiver(*receiver)) {
+    Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure);
+    if (!info->IsCompatibleReceiver(*receiver)) {
       Handle<Object> args[2] = { name, receiver };
       Handle<Object> error =
           isolate->factory()->NewTypeError("incompatible_method_receiver",
@@ -462,6 +462,17 @@ MaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver,
 }
 
 
+bool AccessorInfo::IsCompatibleReceiverType(Isolate* isolate,
+                                            Handle<AccessorInfo> info,
+                                            Handle<HeapType> type) {
+  if (!info->HasExpectedReceiverType()) return true;
+  Handle<Map> map = IC::TypeToMap(*type, isolate);
+  if (!map->IsJSObjectMap()) return false;
+  return FunctionTemplateInfo::cast(info->expected_receiver_type())
+      ->IsTemplateFor(*map);
+}
+
+
 MaybeHandle<Object> Object::SetPropertyWithAccessor(
     Handle<Object> receiver, Handle<Name> name, Handle<Object> value,
     Handle<JSObject> holder, Handle<Object> structure, StrictMode strict_mode) {
@@ -474,8 +485,8 @@ MaybeHandle<Object> Object::SetPropertyWithAccessor(
     // Don't call executable accessor setters with non-JSObject receivers.
     if (!receiver->IsJSObject()) return value;
     // api style callbacks
-    ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure);
-    if (!data->IsCompatibleReceiver(*receiver)) {
+    ExecutableAccessorInfo* info = ExecutableAccessorInfo::cast(*structure);
+    if (!info->IsCompatibleReceiver(*receiver)) {
       Handle<Object> args[2] = { name, receiver };
       Handle<Object> error =
           isolate->factory()->NewTypeError("incompatible_method_receiver",
@@ -485,13 +496,13 @@ MaybeHandle<Object> Object::SetPropertyWithAccessor(
     }
     // TODO(rossberg): Support symbols in the API.
     if (name->IsSymbol()) return value;
-    Object* call_obj = data->setter();
+    Object* call_obj = info->setter();
     v8::AccessorSetterCallback call_fun =
         v8::ToCData<v8::AccessorSetterCallback>(call_obj);
     if (call_fun == NULL) return value;
     Handle<String> key = Handle<String>::cast(name);
     LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name));
-    PropertyCallbackArguments args(isolate, data->data(), *receiver, *holder);
+    PropertyCallbackArguments args(isolate, info->data(), *receiver, *holder);
     args.Call(call_fun,
               v8::Utils::ToLocal(key),
               v8::Utils::ToLocal(value));
index 8b6e00ad648dce688f59086550740cdfa53dad6b..1c0fa6462e0802414c5b8eff2489d5628c1efe15 100644 (file)
@@ -10528,6 +10528,9 @@ class AccessorInfo: public Struct {
   inline void set_property_attributes(PropertyAttributes attributes);
 
   // Checks whether the given receiver is compatible with this accessor.
+  static bool IsCompatibleReceiverType(Isolate* isolate,
+                                       Handle<AccessorInfo> info,
+                                       Handle<HeapType> type);
   inline bool IsCompatibleReceiver(Object* receiver);
 
   DECLARE_CAST(AccessorInfo)
@@ -10547,6 +10550,9 @@ class AccessorInfo: public Struct {
   static const int kSize = kExpectedReceiverTypeOffset + kPointerSize;
 
  private:
+  inline bool HasExpectedReceiverType() {
+    return expected_receiver_type()->IsFunctionTemplateInfo();
+  }
   // Bit positions in flag.
   static const int kAllCanReadBit = 0;
   static const int kAllCanWriteBit = 1;
index eb7195213a9710fe677ce34dcceb107cae249695..3173f4ddf1f24f543448980b873c159bebf4749c 100644 (file)
@@ -203,8 +203,8 @@ Handle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent(
       cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST);
   if (!handler.is_null()) return handler;
 
-  NamedLoadHandlerCompiler compiler(isolate, flag);
-  handler = compiler.CompileLoadNonexistent(type, last, cache_name);
+  NamedLoadHandlerCompiler compiler(isolate, type, flag);
+  handler = compiler.CompileLoadNonexistent(last, cache_name);
   Map::UpdateCodeCache(stub_holder_map, cache_name, handler);
   return handler;
 }
@@ -497,25 +497,27 @@ void StubCache::CollectMatchingMaps(SmallMapList* types,
 
 
 RUNTIME_FUNCTION(StoreCallbackProperty) {
-  JSObject* receiver = JSObject::cast(args[0]);
-  JSObject* holder = JSObject::cast(args[1]);
-  ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[2]);
+  Handle<JSObject> receiver = args.at<JSObject>(0);
+  Handle<JSObject> holder = args.at<JSObject>(1);
+  Handle<ExecutableAccessorInfo> callback = args.at<ExecutableAccessorInfo>(2);
+  Handle<Name> name = args.at<Name>(3);
+  Handle<Object> value = args.at<Object>(4);
+  HandleScope scope(isolate);
+
+  ASSERT(callback->IsCompatibleReceiver(*receiver));
+
   Address setter_address = v8::ToCData<Address>(callback->setter());
   v8::AccessorSetterCallback fun =
       FUNCTION_CAST<v8::AccessorSetterCallback>(setter_address);
   ASSERT(fun != NULL);
-  ASSERT(callback->IsCompatibleReceiver(receiver));
-  Handle<Name> name = args.at<Name>(3);
-  Handle<Object> value = args.at<Object>(4);
-  HandleScope scope(isolate);
 
   // TODO(rossberg): Support symbols in the API.
   if (name->IsSymbol()) return *value;
   Handle<String> str = Handle<String>::cast(name);
 
-  LOG(isolate, ApiNamedPropertyAccess("store", receiver, *name));
-  PropertyCallbackArguments
-      custom_args(isolate, callback->data(), receiver, holder);
+  LOG(isolate, ApiNamedPropertyAccess("store", *receiver, *name));
+  PropertyCallbackArguments custom_args(isolate, callback->data(), *receiver,
+                                        *holder);
   custom_args.Call(fun, v8::Utils::ToLocal(str), v8::Utils::ToLocal(value));
   RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
   return *value;
@@ -746,20 +748,19 @@ Handle<Code> PropertyAccessCompiler::GetCodeWithFlags(Code::Flags flags,
 #define __ ACCESS_MASM(masm())
 
 
-Register NamedLoadHandlerCompiler::FrontendHeader(Handle<HeapType> type,
-                                                  Register object_reg,
+Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg,
                                                   Handle<JSObject> holder,
                                                   Handle<Name> name,
                                                   Label* miss) {
   PrototypeCheckType check_type = CHECK_ALL_MAPS;
   int function_index = -1;
-  if (type->Is(HeapType::String())) {
+  if (type()->Is(HeapType::String())) {
     function_index = Context::STRING_FUNCTION_INDEX;
-  } else if (type->Is(HeapType::Symbol())) {
+  } else if (type()->Is(HeapType::Symbol())) {
     function_index = Context::SYMBOL_FUNCTION_INDEX;
-  } else if (type->Is(HeapType::Number())) {
+  } else if (type()->Is(HeapType::Number())) {
     function_index = Context::NUMBER_FUNCTION_INDEX;
-  } else if (type->Is(HeapType::Boolean())) {
+  } else if (type()->Is(HeapType::Boolean())) {
     function_index = Context::BOOLEAN_FUNCTION_INDEX;
   } else {
     check_type = SKIP_RECEIVER;
@@ -770,26 +771,24 @@ Register NamedLoadHandlerCompiler::FrontendHeader(Handle<HeapType> type,
         masm(), function_index, scratch1(), miss);
     Object* function = isolate()->native_context()->get(function_index);
     Object* prototype = JSFunction::cast(function)->instance_prototype();
-    type = IC::CurrentTypeOf(handle(prototype, isolate()), isolate());
+    set_type_for_object(handle(prototype, isolate()));
     object_reg = scratch1();
   }
 
   // Check that the maps starting from the prototype haven't changed.
-  return CheckPrototypes(
-      type, object_reg, holder, scratch1(), scratch2(), scratch3(),
-      name, miss, check_type);
+  return CheckPrototypes(object_reg, holder, scratch1(), scratch2(), scratch3(),
+                         name, miss, check_type);
 }
 
 
 // Frontend for store uses the name register. It has to be restored before a
 // miss.
-Register NamedStoreHandlerCompiler::FrontendHeader(Handle<HeapType> type,
-                                                   Register object_reg,
+Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg,
                                                    Handle<JSObject> holder,
                                                    Handle<Name> name,
                                                    Label* miss) {
-  return CheckPrototypes(type, object_reg, holder, this->name(),
-                         scratch1(), scratch2(), name, miss, SKIP_RECEIVER);
+  return CheckPrototypes(object_reg, holder, this->name(), scratch1(),
+                         scratch2(), name, miss, SKIP_RECEIVER);
 }
 
 
@@ -801,19 +800,17 @@ bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) {
 }
 
 
-Register PropertyHandlerCompiler::Frontend(Handle<HeapType> type,
-                                           Register object_reg,
+Register PropertyHandlerCompiler::Frontend(Register object_reg,
                                            Handle<JSObject> holder,
                                            Handle<Name> name) {
   Label miss;
-  Register reg = FrontendHeader(type, object_reg, holder, name, &miss);
+  Register reg = FrontendHeader(object_reg, holder, name, &miss);
   FrontendFooter(name, &miss);
   return reg;
 }
 
 
-void NamedLoadHandlerCompiler::NonexistentFrontend(Handle<HeapType> type,
-                                                   Handle<JSObject> last,
+void NamedLoadHandlerCompiler::NonexistentFrontend(Handle<JSObject> last,
                                                    Handle<Name> name) {
   Label miss;
 
@@ -821,11 +818,11 @@ void NamedLoadHandlerCompiler::NonexistentFrontend(Handle<HeapType> type,
   Handle<Map> last_map;
   if (last.is_null()) {
     holder = receiver();
-    last_map = IC::TypeToMap(*type, isolate());
+    last_map = IC::TypeToMap(*type(), isolate());
     // If |type| has null as its prototype, |last| is Handle<JSObject>::null().
     ASSERT(last_map->prototype() == isolate()->heap()->null_value());
   } else {
-    holder = FrontendHeader(type, receiver(), last, name, &miss);
+    holder = FrontendHeader(receiver(), last, name, &miss);
     last_map = handle(last->map());
   }
 
@@ -846,9 +843,10 @@ void NamedLoadHandlerCompiler::NonexistentFrontend(Handle<HeapType> type,
   // If the last object in the prototype chain is a global object,
   // check that the global property cell is empty.
   if (last_map->IsJSGlobalObjectMap()) {
-    Handle<JSGlobalObject> global = last.is_null()
-        ? Handle<JSGlobalObject>::cast(type->AsConstant()->Value())
-        : Handle<JSGlobalObject>::cast(last);
+    Handle<JSGlobalObject> global =
+        last.is_null()
+            ? Handle<JSGlobalObject>::cast(type()->AsConstant()->Value())
+            : Handle<JSGlobalObject>::cast(last);
     GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss);
   }
 
@@ -857,39 +855,38 @@ void NamedLoadHandlerCompiler::NonexistentFrontend(Handle<HeapType> type,
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField(
-    Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name,
-    FieldIndex field, Representation representation) {
-  Register reg = Frontend(type, receiver(), holder, name);
+    Handle<JSObject> holder, Handle<Name> name, FieldIndex field,
+    Representation representation) {
+  Register reg = Frontend(receiver(), holder, name);
   GenerateLoadField(reg, holder, field, representation);
   return GetCode(kind(), Code::FAST, name);
 }
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(
-    Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name,
-    Handle<Object> value) {
-  Frontend(type, receiver(), holder, name);
+    Handle<JSObject> holder, Handle<Name> name, Handle<Object> value) {
+  Frontend(receiver(), holder, name);
   GenerateLoadConstant(value);
   return GetCode(kind(), Code::FAST, name);
 }
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
-    Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name,
+    Handle<JSObject> holder, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
-  Register reg = CallbackFrontend(type, receiver(), holder, name, callback);
+  Register reg = CallbackFrontend(receiver(), holder, name, callback);
   GenerateLoadCallback(reg, callback);
   return GetCode(kind(), Code::FAST, name);
 }
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
-    Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name,
+    Handle<JSObject> holder, Handle<Name> name,
     const CallOptimization& call_optimization) {
   ASSERT(call_optimization.is_simple_api_call());
   Handle<JSFunction> callback = call_optimization.constant_function();
-  CallbackFrontend(type, receiver(), holder, name, callback);
-  Handle<Map>receiver_map = IC::TypeToMap(*type, isolate());
+  CallbackFrontend(receiver(), holder, name, callback);
+  Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
   GenerateFastApiCall(
       masm(), call_optimization, receiver_map,
       receiver(), scratch1(), false, 0, NULL);
@@ -898,7 +895,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
-    Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name) {
+    Handle<JSObject> holder, Handle<Name> name) {
   // Perform a lookup after the interceptor.
   LookupResult lookup(isolate());
   holder->LookupOwnRealNamedProperty(name, &lookup);
@@ -909,10 +906,10 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
     }
   }
 
-  Register reg = Frontend(type, receiver(), holder, name);
+  Register reg = Frontend(receiver(), holder, name);
   // TODO(368): Compile in the whole chain: all the interceptors in
   // prototypes and ultimate answer.
-  GenerateLoadInterceptor(reg, type, holder, &lookup, name);
+  GenerateLoadInterceptor(reg, holder, &lookup, name);
   return GetCode(kind(), Code::FAST, name);
 }
 
@@ -929,8 +926,8 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
     } else {
       // We found FIELD property in prototype chain of interceptor's holder.
       // Retrieve a field from field's holder.
-      Register reg = Frontend(IC::CurrentTypeOf(interceptor_holder, isolate()),
-                              interceptor_reg, holder, name);
+      set_type_for_object(interceptor_holder);
+      Register reg = Frontend(interceptor_reg, holder, name);
       GenerateLoadField(
           reg, holder, field, lookup->representation());
     }
@@ -942,9 +939,8 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
         ExecutableAccessorInfo::cast(lookup->GetCallbackObject()));
     ASSERT(callback->getter() != NULL);
 
-    Register reg =
-        CallbackFrontend(IC::CurrentTypeOf(interceptor_holder, isolate()),
-                         interceptor_reg, holder, name, callback);
+    set_type_for_object(interceptor_holder);
+    Register reg = CallbackFrontend(interceptor_reg, holder, name, callback);
     GenerateLoadCallback(reg, callback);
   }
 }
@@ -964,10 +960,9 @@ Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type,
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
-    Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name,
-    Handle<JSFunction> getter) {
-  Frontend(type, receiver(), holder, name);
-  GenerateLoadViaGetter(masm(), type, receiver(), getter);
+    Handle<JSObject> holder, Handle<Name> name, Handle<JSFunction> getter) {
+  Frontend(receiver(), holder, name);
+  GenerateLoadViaGetter(masm(), type(), receiver(), getter);
   return GetCode(kind(), Code::FAST, name);
 }
 
@@ -995,8 +990,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
       } while (!iter.IsAtEnd());
     }
 
-    Register holder_reg = FrontendHeader(IC::CurrentTypeOf(object, isolate()),
-                                         receiver(), holder, name, &miss);
+    Register holder_reg = FrontendHeader(receiver(), holder, name, &miss);
 
     // If no property was found, and the holder (the last object in the
     // prototype chain) is in slow mode, we need to do a negative lookup on the
@@ -1030,8 +1024,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(
     Handle<JSObject> object, LookupResult* lookup, Handle<Name> name) {
   Label miss;
 
-  FrontendHeader(IC::CurrentTypeOf(object, isolate()), receiver(), object, name,
-                 &miss);
+  FrontendHeader(receiver(), object, name, &miss);
 
   // Generate store field code.
   GenerateStoreField(masm(),
@@ -1071,9 +1064,8 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreArrayLength(
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
     Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
     Handle<JSFunction> setter) {
-  Handle<HeapType> type = IC::CurrentTypeOf(object, isolate());
-  Frontend(type, receiver(), holder, name);
-  GenerateStoreViaSetter(masm(), type, receiver(), setter);
+  Frontend(receiver(), holder, name);
+  GenerateStoreViaSetter(masm(), type(), receiver(), setter);
 
   return GetCode(kind(), Code::FAST, name);
 }
@@ -1082,7 +1074,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
     const CallOptimization& call_optimization) {
-  Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
+  Frontend(receiver(), holder, name);
   Register values[] = { value() };
   GenerateFastApiCall(
       masm(), call_optimization, handle(object->map()),
index 263331a7a0bd85dcd010386a08b50bee7f0e826c..f3a330b8a36f81236c86567beb1786395c436a1a 100644 (file)
@@ -374,22 +374,21 @@ class PropertyHandlerCompiler : public PropertyAccessCompiler {
 
  protected:
   PropertyHandlerCompiler(Isolate* isolate, Code::Kind kind,
-                          CacheHolderFlag cache_holder)
-      : PropertyAccessCompiler(isolate, kind, cache_holder) {}
+                          Handle<HeapType> type, CacheHolderFlag cache_holder)
+      : PropertyAccessCompiler(isolate, kind, cache_holder), type_(type) {}
 
   virtual ~PropertyHandlerCompiler() {}
 
-  virtual Register FrontendHeader(Handle<HeapType> type, Register object_reg,
-                                  Handle<JSObject> holder, Handle<Name> name,
-                                  Label* miss) {
+  virtual Register FrontendHeader(Register object_reg, Handle<JSObject> holder,
+                                  Handle<Name> name, Label* miss) {
     UNREACHABLE();
     return receiver();
   }
 
   virtual void FrontendFooter(Handle<Name> name, Label* miss) { UNREACHABLE(); }
 
-  Register Frontend(Handle<HeapType> type, Register object_reg,
-                    Handle<JSObject> holder, Handle<Name> name);
+  Register Frontend(Register object_reg, Handle<JSObject> holder,
+                    Handle<Name> name);
 
   // TODO(verwaest): Make non-static.
   static void GenerateFastApiCall(MacroAssembler* masm,
@@ -431,67 +430,56 @@ class PropertyHandlerCompiler : public PropertyAccessCompiler {
   // register is only clobbered if it the same as the holder register. The
   // function returns a register containing the holder - either object_reg or
   // holder_reg.
-  Register CheckPrototypes(Handle<HeapType> type,
-                           Register object_reg,
-                           Handle<JSObject> holder,
-                           Register holder_reg,
-                           Register scratch1,
-                           Register scratch2,
-                           Handle<Name> name,
-                           Label* miss,
+  Register CheckPrototypes(Register object_reg, Handle<JSObject> holder,
+                           Register holder_reg, Register scratch1,
+                           Register scratch2, Handle<Name> name, Label* miss,
                            PrototypeCheckType check = CHECK_ALL_MAPS);
 
   Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name);
+  void set_type_for_object(Handle<Object> object) {
+    type_ = IC::CurrentTypeOf(object, isolate());
+  }
+  Handle<HeapType> type() const { return type_; }
+
+ private:
+  Handle<HeapType> type_;
 };
 
 
 class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
  public:
-  NamedLoadHandlerCompiler(Isolate* isolate,
-                           CacheHolderFlag cache_holder = kCacheOnReceiver)
-      : PropertyHandlerCompiler(isolate, Code::LOAD_IC, cache_holder) {}
+  NamedLoadHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
+                           CacheHolderFlag cache_holder)
+      : PropertyHandlerCompiler(isolate, Code::LOAD_IC, type, cache_holder) {}
 
   virtual ~NamedLoadHandlerCompiler() {}
 
-  Handle<Code> CompileLoadField(Handle<HeapType> type,
-                                Handle<JSObject> holder,
-                                Handle<Name> name,
+  Handle<Code> CompileLoadField(Handle<JSObject> holder, Handle<Name> name,
                                 FieldIndex index,
                                 Representation representation);
 
-  Handle<Code> CompileLoadCallback(Handle<HeapType> type,
-                                   Handle<JSObject> holder,
-                                   Handle<Name> name,
+  Handle<Code> CompileLoadCallback(Handle<JSObject> holder, Handle<Name> name,
                                    Handle<ExecutableAccessorInfo> callback);
 
-  Handle<Code> CompileLoadCallback(Handle<HeapType> type,
-                                   Handle<JSObject> holder,
-                                   Handle<Name> name,
+  Handle<Code> CompileLoadCallback(Handle<JSObject> holder, Handle<Name> name,
                                    const CallOptimization& call_optimization);
 
-  Handle<Code> CompileLoadConstant(Handle<HeapType> type,
-                                   Handle<JSObject> holder,
-                                   Handle<Name> name,
+  Handle<Code> CompileLoadConstant(Handle<JSObject> holder, Handle<Name> name,
                                    Handle<Object> value);
 
-  Handle<Code> CompileLoadInterceptor(Handle<HeapType> type,
-                                      Handle<JSObject> holder,
+  Handle<Code> CompileLoadInterceptor(Handle<JSObject> holder,
                                       Handle<Name> name);
 
-  Handle<Code> CompileLoadViaGetter(Handle<HeapType> type,
-                                    Handle<JSObject> holder,
-                                    Handle<Name> name,
+  Handle<Code> CompileLoadViaGetter(Handle<JSObject> holder, Handle<Name> name,
                                     Handle<JSFunction> getter);
 
+  Handle<Code> CompileLoadGlobal(Handle<GlobalObject> holder,
+                                 Handle<PropertyCell> cell, Handle<Name> name,
+                                 bool is_dont_delete);
+
   static Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
                                              Handle<HeapType> type);
 
-  Handle<Code> CompileLoadGlobal(Handle<HeapType> type,
-                                 Handle<GlobalObject> holder,
-                                 Handle<PropertyCell> cell,
-                                 Handle<Name> name,
-                                 bool is_dont_delete);
-
   static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<HeapType> type,
                                     Register receiver,
                                     Handle<JSFunction> getter);
@@ -518,20 +506,16 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
   static const int kInterceptorArgsLength = 4;
 
  protected:
-  virtual Register FrontendHeader(Handle<HeapType> type, Register object_reg,
-                                  Handle<JSObject> holder, Handle<Name> name,
-                                  Label* miss);
+  virtual Register FrontendHeader(Register object_reg, Handle<JSObject> holder,
+                                  Handle<Name> name, Label* miss);
 
   virtual void FrontendFooter(Handle<Name> name, Label* miss);
 
  private:
-  Register CallbackFrontend(Handle<HeapType> type, Register object_reg,
-                            Handle<JSObject> holder, Handle<Name> name,
-                            Handle<Object> callback);
-  Handle<Code> CompileLoadNonexistent(Handle<HeapType> type,
-                                      Handle<JSObject> last, Handle<Name> name);
-  void NonexistentFrontend(Handle<HeapType> type, Handle<JSObject> last,
-                           Handle<Name> name);
+  Register CallbackFrontend(Register object_reg, Handle<JSObject> holder,
+                            Handle<Name> name, Handle<Object> callback);
+  Handle<Code> CompileLoadNonexistent(Handle<JSObject> last, Handle<Name> name);
+  void NonexistentFrontend(Handle<JSObject> last, Handle<Name> name);
 
   void GenerateLoadField(Register reg,
                          Handle<JSObject> holder,
@@ -543,7 +527,6 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
   void GenerateLoadCallback(const CallOptimization& call_optimization,
                             Handle<Map> receiver_map);
   void GenerateLoadInterceptor(Register holder_reg,
-                               Handle<Object> object,
                                Handle<JSObject> holder,
                                LookupResult* lookup,
                                Handle<Name> name);
@@ -570,8 +553,9 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
 
 class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
  public:
-  explicit NamedStoreHandlerCompiler(Isolate* isolate)
-      : PropertyHandlerCompiler(isolate, Code::STORE_IC, kCacheOnReceiver) {}
+  explicit NamedStoreHandlerCompiler(Isolate* isolate, Handle<HeapType> type)
+      : PropertyHandlerCompiler(isolate, Code::STORE_IC, type,
+                                kCacheOnReceiver) {}
 
   virtual ~NamedStoreHandlerCompiler() {}
 
@@ -614,9 +598,8 @@ class NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
   }
 
  protected:
-  virtual Register FrontendHeader(Handle<HeapType> type, Register object_reg,
-                                  Handle<JSObject> holder, Handle<Name> name,
-                                  Label* miss);
+  virtual Register FrontendHeader(Register object_reg, Handle<JSObject> holder,
+                                  Handle<Name> name, Label* miss);
 
   virtual void FrontendFooter(Handle<Name> name, Label* miss);
   void GenerateRestoreName(MacroAssembler* masm, Label* label,
@@ -672,7 +655,7 @@ class ElementHandlerCompiler : public PropertyHandlerCompiler {
  public:
   explicit ElementHandlerCompiler(Isolate* isolate)
       : PropertyHandlerCompiler(isolate, Code::KEYED_LOAD_IC,
-                                kCacheOnReceiver) {}
+                                Handle<HeapType>::null(), kCacheOnReceiver) {}
 
   virtual ~ElementHandlerCompiler() {}
 
index c2638942d7f9d65e679bc1191acfd270149c74dc..358605c0617770b4cc4a7eb50d9f49703ecb3f21 100644 (file)
@@ -633,10 +633,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, 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()));
 
   // Make sure there's no overlap between holder and object registers.
   ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
@@ -650,8 +650,8 @@ 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;
@@ -765,14 +765,13 @@ void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
 }
 
 
-Register NamedLoadHandlerCompiler::CallbackFrontend(Handle<HeapType> type,
-                                                    Register object_reg,
+Register NamedLoadHandlerCompiler::CallbackFrontend(Register object_reg,
                                                     Handle<JSObject> holder,
                                                     Handle<Name> name,
                                                     Handle<Object> callback) {
   Label miss;
 
-  Register reg = FrontendHeader(type, object_reg, holder, name, &miss);
+  Register reg = FrontendHeader(object_reg, holder, name, &miss);
 
   if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
     ASSERT(!reg.is(scratch2()));
@@ -875,9 +874,8 @@ void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
 
 
 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
-    Register holder_reg, Handle<Object> object,
-    Handle<JSObject> interceptor_holder, LookupResult* lookup,
-    Handle<Name> name) {
+    Register holder_reg, Handle<JSObject> interceptor_holder,
+    LookupResult* lookup, Handle<Name> name) {
   ASSERT(interceptor_holder->HasNamedInterceptor());
   ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
 
@@ -890,10 +888,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());
     }
   }
 
@@ -967,8 +967,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptor(
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg =
-      Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name);
+  Register holder_reg = Frontend(receiver(), holder, name);
 
   __ PopReturnAddressTo(scratch1());
   __ Push(receiver());
@@ -1103,8 +1102,8 @@ Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
-    Handle<HeapType> type, Handle<JSObject> last, Handle<Name> name) {
-  NonexistentFrontend(type, last, name);
+    Handle<JSObject> last, Handle<Name> name) {
+  NonexistentFrontend(last, name);
 
   // Return undefined if maps of the full prototype chain are still the
   // same and no global property with this name contains a value.
@@ -1192,30 +1191,27 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
-    Handle<HeapType> type, Handle<GlobalObject> global,
-    Handle<PropertyCell> cell, Handle<Name> name, bool is_dont_delete) {
+    Handle<GlobalObject> global, Handle<PropertyCell> cell, Handle<Name> name,
+    bool is_dont_delete) {
   Label miss;
-  // TODO(verwaest): Directly store to rax. Currently we cannot do this, since
-  // rax is used as receiver(), which we would otherwise clobber before a
-  // potential miss.
-  FrontendHeader(type, receiver(), global, name, &miss);
+  FrontendHeader(receiver(), global, name, &miss);
 
   // Get the value from the cell.
-  __ Move(rbx, cell);
-  __ movp(rbx, FieldOperand(rbx, PropertyCell::kValueOffset));
+  Register result = StoreIC::ValueRegister();
+  __ Move(result, cell);
+  __ movp(result, FieldOperand(result, PropertyCell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
   if (!is_dont_delete) {
-    __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
+    __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
     __ j(equal, &miss);
   } else if (FLAG_debug_code) {
-    __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
+    __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
     __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
   }
 
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->named_load_global_stub(), 1);
-  __ movp(rax, rbx);
   __ ret(0);
 
   FrontendFooter(name, &miss);