Load getter from map descriptor instead of embedding it in handler.
authorulan <ulan@chromium.org>
Mon, 26 Jan 2015 15:42:06 +0000 (07:42 -0800)
committerCommit bot <commit-bot@chromium.org>
Mon, 26 Jan 2015 15:42:14 +0000 (15:42 +0000)
BUG=v8:3629
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#26275}

12 files changed:
src/ic/arm/handler-compiler-arm.cc
src/ic/arm64/handler-compiler-arm64.cc
src/ic/handler-compiler.cc
src/ic/handler-compiler.h
src/ic/ia32/handler-compiler-ia32.cc
src/ic/ic.cc
src/ic/mips/handler-compiler-mips.cc
src/ic/mips64/handler-compiler-mips64.cc
src/ic/x64/handler-compiler-x64.cc
src/ic/x87/handler-compiler-x87.cc
src/lookup.cc
src/lookup.h

index c99e06a..c4f95a4 100644 (file)
@@ -18,7 +18,7 @@ namespace internal {
 
 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
     MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
+    Register holder, int accessor_index, int expected_arguments) {
   // ----------- S t a t e -------------
   //  -- r0    : receiver
   //  -- r2    : name
@@ -27,7 +27,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
   {
     FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
 
-    if (!getter.is_null()) {
+    if (accessor_index >= 0) {
       // Call the JavaScript getter with the receiver on the stack.
       if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
         // Swap in the global receiver.
@@ -36,9 +36,14 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
       }
       __ push(receiver);
       ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
+      ParameterCount expected(expected_arguments);
+      Register scratch = holder;
+      __ ldr(scratch, FieldMemOperand(holder, HeapObject::kMapOffset));
+      __ LoadInstanceDescriptors(scratch, scratch);
+      __ ldr(scratch, FieldMemOperand(scratch, DescriptorArray::GetValueOffset(
+                                                   accessor_index)));
+      __ ldr(r1, FieldMemOperand(scratch, AccessorPair::kGetterOffset));
+      __ InvokeFunction(r1, expected, actual, CALL_FUNCTION, NullCallWrapper());
     } else {
       // If we generate a global code snippet for deoptimization only, remember
       // the place to continue after deoptimization.
index f434f2e..53f084b 100644 (file)
@@ -263,11 +263,11 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
 
 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
     MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
+    Register holder, int accessor_index, int expected_arguments) {
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
-    if (!getter.is_null()) {
+    if (accessor_index >= 0) {
       // Call the JavaScript getter with the receiver on the stack.
       if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
         // Swap in the global receiver.
@@ -276,9 +276,14 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
       }
       __ Push(receiver);
       ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
+      ParameterCount expected(expected_arguments);
+      Register scratch = holder;
+      __ Ldr(scratch, FieldMemOperand(holder, HeapObject::kMapOffset));
+      __ LoadInstanceDescriptors(scratch, scratch);
+      __ Ldr(scratch, FieldMemOperand(scratch, DescriptorArray::GetValueOffset(
+                                                   accessor_index)));
+      __ Ldr(x1, FieldMemOperand(scratch, AccessorPair::kGetterOffset));
+      __ InvokeFunction(x1, expected, actual, CALL_FUNCTION, NullCallWrapper());
     } else {
       // If we generate a global code snippet for deoptimization only, remember
       // the place to continue after deoptimization.
index 6f82543..b39a172 100644 (file)
@@ -353,9 +353,10 @@ void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor(
 
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
-    Handle<Name> name, Handle<JSFunction> getter) {
-  Frontend(name);
-  GenerateLoadViaGetter(masm(), type(), receiver(), getter);
+    Handle<Name> name, int accessor_index, int expected_arguments) {
+  Register holder = Frontend(name);
+  GenerateLoadViaGetter(masm(), type(), receiver(), holder, accessor_index,
+                        expected_arguments);
   return GetCode(kind(), Code::FAST, name);
 }
 
index 7d6b424..e25aed1 100644 (file)
@@ -133,8 +133,8 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
   // inlined.
   Handle<Code> CompileLoadInterceptor(LookupIterator* it);
 
-  Handle<Code> CompileLoadViaGetter(Handle<Name> name,
-                                    Handle<JSFunction> getter);
+  Handle<Code> CompileLoadViaGetter(Handle<Name> name, int accessor_index,
+                                    int expected_arguments);
 
   Handle<Code> CompileLoadGlobal(Handle<PropertyCell> cell, Handle<Name> name,
                                  bool is_configurable);
@@ -144,12 +144,12 @@ class NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
                                              Handle<HeapType> type);
 
   static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<HeapType> type,
-                                    Register receiver,
-                                    Handle<JSFunction> getter);
+                                    Register receiver, Register holder,
+                                    int accessor_index, int expected_arguments);
 
   static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm) {
-    GenerateLoadViaGetter(masm, Handle<HeapType>::null(), no_reg,
-                          Handle<JSFunction>());
+    GenerateLoadViaGetter(masm, Handle<HeapType>::null(), no_reg, no_reg, -1,
+                          -1);
   }
 
   static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
index f20d75f..ffc38a4 100644 (file)
@@ -18,11 +18,11 @@ namespace internal {
 
 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
     MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
+    Register holder, int accessor_index, int expected_arguments) {
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
-    if (!getter.is_null()) {
+    if (accessor_index >= 0) {
       // Call the JavaScript getter with the receiver on the stack.
       if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
         // Swap in the global receiver.
@@ -31,8 +31,14 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
       }
       __ push(receiver);
       ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+      ParameterCount expected(expected_arguments);
+      Register scratch = holder;
+      __ mov(scratch, FieldOperand(holder, HeapObject::kMapOffset));
+      __ LoadInstanceDescriptors(scratch, scratch);
+      __ mov(scratch, FieldOperand(scratch, DescriptorArray::GetValueOffset(
+                                                accessor_index)));
+      __ mov(edi, FieldOperand(scratch, AccessorPair::kGetterOffset));
+      __ InvokeFunction(edi, expected, actual, CALL_FUNCTION,
                         NullCallWrapper());
     } else {
       // If we generate a global code snippet for deoptimization only, remember
index 8cd0686..f6fffea 100644 (file)
@@ -1229,7 +1229,9 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup,
           return compiler.CompileLoadCallback(lookup->name(),
                                               call_optimization);
         }
-        return compiler.CompileLoadViaGetter(lookup->name(), function);
+        int expected_arguments = function->shared()->formal_parameter_count();
+        return compiler.CompileLoadViaGetter(
+            lookup->name(), lookup->GetAccessorIndex(), expected_arguments);
       }
       break;
     }
index 6c9e006..00c3242 100644 (file)
@@ -18,7 +18,7 @@ namespace internal {
 
 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
     MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
+    Register holder, int accessor_index, int expected_arguments) {
   // ----------- S t a t e -------------
   //  -- a0    : receiver
   //  -- a2    : name
@@ -27,7 +27,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
-    if (!getter.is_null()) {
+    if (accessor_index >= 0) {
       // Call the JavaScript getter with the receiver on the stack.
       if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
         // Swap in the global receiver.
@@ -36,9 +36,14 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
       }
       __ push(receiver);
       ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
+      ParameterCount expected(expected_arguments);
+      Register scratch = holder;
+      __ lw(scratch, FieldMemOperand(holder, HeapObject::kMapOffset));
+      __ LoadInstanceDescriptors(scratch, scratch);
+      __ lw(scratch, FieldMemOperand(scratch, DescriptorArray::GetValueOffset(
+                                                  accessor_index)));
+      __ lw(a1, FieldMemOperand(scratch, AccessorPair::kGetterOffset));
+      __ InvokeFunction(a1, expected, actual, CALL_FUNCTION, NullCallWrapper());
     } else {
       // If we generate a global code snippet for deoptimization only, remember
       // the place to continue after deoptimization.
index e612f63..56cfb15 100644 (file)
@@ -18,7 +18,7 @@ namespace internal {
 
 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
     MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
+    Register holder, int accessor_index, int expected_arguments) {
   // ----------- S t a t e -------------
   //  -- a0    : receiver
   //  -- a2    : name
@@ -27,7 +27,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
-    if (!getter.is_null()) {
+    if (accessor_index >= 0) {
       // Call the JavaScript getter with the receiver on the stack.
       if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
         // Swap in the global receiver.
@@ -36,9 +36,14 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
       }
       __ push(receiver);
       ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
-                        NullCallWrapper());
+      ParameterCount expected(expected_arguments);
+      Register scratch = holder;
+      __ ld(scratch, FieldMemOperand(holder, HeapObject::kMapOffset));
+      __ LoadInstanceDescriptors(scratch, scratch);
+      __ ld(scratch, FieldMemOperand(scratch, DescriptorArray::GetValueOffset(
+                                                  accessor_index)));
+      __ ld(a1, FieldMemOperand(scratch, AccessorPair::kGetterOffset));
+      __ InvokeFunction(a1, expected, actual, CALL_FUNCTION, NullCallWrapper());
     } else {
       // If we generate a global code snippet for deoptimization only, remember
       // the place to continue after deoptimization.
index 1538f12..13b5fa8 100644 (file)
@@ -255,7 +255,7 @@ void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
 
 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
     MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
+    Register holder, int accessor_index, int expected_arguments) {
   // ----------- S t a t e -------------
   //  -- rax    : receiver
   //  -- rcx    : name
@@ -264,7 +264,7 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
-    if (!getter.is_null()) {
+    if (accessor_index >= 0) {
       // Call the JavaScript getter with the receiver on the stack.
       if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
         // Swap in the global receiver.
@@ -273,8 +273,14 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
       }
       __ Push(receiver);
       ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+      ParameterCount expected(expected_arguments);
+      Register scratch = holder;
+      __ movp(scratch, FieldOperand(holder, HeapObject::kMapOffset));
+      __ LoadInstanceDescriptors(scratch, scratch);
+      __ movp(scratch, FieldOperand(scratch, DescriptorArray::GetValueOffset(
+                                                 accessor_index)));
+      __ movp(rdi, FieldOperand(scratch, AccessorPair::kGetterOffset));
+      __ InvokeFunction(rdi, expected, actual, CALL_FUNCTION,
                         NullCallWrapper());
     } else {
       // If we generate a global code snippet for deoptimization only, remember
index 0540faf..ccab527 100644 (file)
@@ -18,11 +18,11 @@ namespace internal {
 
 void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
     MacroAssembler* masm, Handle<HeapType> type, Register receiver,
-    Handle<JSFunction> getter) {
+    Register holder, int accessor_index, int expected_arguments) {
   {
     FrameScope scope(masm, StackFrame::INTERNAL);
 
-    if (!getter.is_null()) {
+    if (accessor_index >= 0) {
       // Call the JavaScript getter with the receiver on the stack.
       if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
         // Swap in the global receiver.
@@ -31,8 +31,14 @@ void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
       }
       __ push(receiver);
       ParameterCount actual(0);
-      ParameterCount expected(getter);
-      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+      ParameterCount expected(expected_arguments);
+      Register scratch = holder;
+      __ mov(scratch, FieldOperand(holder, HeapObject::kMapOffset));
+      __ LoadInstanceDescriptors(scratch, scratch);
+      __ mov(scratch, FieldOperand(scratch, DescriptorArray::GetValueOffset(
+                                                accessor_index)));
+      __ mov(edi, FieldOperand(scratch, AccessorPair::kGetterOffset));
+      __ InvokeFunction(edi, expected, actual, CALL_FUNCTION,
                         NullCallWrapper());
     } else {
       // If we generate a global code snippet for deoptimization only, remember
index e475117..c658a90 100644 (file)
@@ -238,6 +238,14 @@ Handle<Object> LookupIterator::FetchValue() const {
 }
 
 
+int LookupIterator::GetAccessorIndex() const {
+  DCHECK(has_property_);
+  DCHECK(!holder_map_->is_dictionary_map());
+  DCHECK_EQ(v8::internal::ACCESSOR_CONSTANT, property_details_.type());
+  return descriptor_number();
+}
+
+
 int LookupIterator::GetConstantIndex() const {
   DCHECK(has_property_);
   DCHECK(!holder_map_->is_dictionary_map());
index 7af3d9c..01fa766 100644 (file)
@@ -132,6 +132,7 @@ class LookupIterator FINAL BASE_EMBEDDED {
   }
   FieldIndex GetFieldIndex() const;
   Handle<HeapType> GetFieldType() const;
+  int GetAccessorIndex() const;
   int GetConstantIndex() const;
   Handle<PropertyCell> GetPropertyCell() const;
   Handle<Object> GetAccessors() const;