Revision: 22391
Author:   [email protected]
Date:     Tue Jul 15 08:07:25 2014 UTC
Log: Drop unnecessary receiver validity checks from {Load,Store}IC_Normal.

Since these builtins are used as handlers after a map check/dispatch, they don't need to check the receiver again.

[email protected]

Review URL: https://codereview.chromium.org/390053002
http://code.google.com/p/v8/source/detail?r=22391

Modified:
 /branches/bleeding_edge/src/arm/ic-arm.cc
 /branches/bleeding_edge/src/arm64/ic-arm64.cc
 /branches/bleeding_edge/src/ia32/ic-ia32.cc
 /branches/bleeding_edge/src/x64/ic-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/ic-arm.cc   Mon Jul 14 20:43:41 2014 UTC
+++ /branches/bleeding_edge/src/arm/ic-arm.cc   Tue Jul 15 08:07:25 2014 UTC
@@ -37,48 +37,6 @@
   __ cmp(type, Operand(JS_GLOBAL_PROXY_TYPE));
   __ b(eq, global_object);
 }
-
-
-// Generated code falls through if the receiver is a regular non-global
-// JS object with slow properties and no interceptors.
-static void GenerateNameDictionaryReceiverCheck(MacroAssembler* masm,
-                                                Register receiver,
-                                                Register elements,
-                                                Register t0,
-                                                Register t1,
-                                                Label* miss) {
-  // Register usage:
-  //   receiver: holds the receiver on entry and is unchanged.
-  //   elements: holds the property dictionary on fall through.
-  // Scratch registers:
-  //   t0: used to holds the receiver map.
-  //   t1: used to holds the receiver instance type, receiver bit mask and
-  //       elements map.
-
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, miss);
-
-  // Check that the receiver is a valid JS object.
-  __ CompareObjectType(receiver, t0, t1, FIRST_SPEC_OBJECT_TYPE);
-  __ b(lt, miss);
-
-  // If this assert fails, we have to check upper bound too.
-  STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
-
-  GenerateGlobalInstanceTypeCheck(masm, t1, miss);
-
-  // Check that the global object does not require access checks.
-  __ ldrb(t1, FieldMemOperand(t0, Map::kBitFieldOffset));
-  __ tst(t1, Operand((1 << Map::kIsAccessCheckNeeded) |
-                     (1 << Map::kHasNamedInterceptor)));
-  __ b(ne, miss);
-
-  __ ldr(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
-  __ ldr(t1, FieldMemOperand(elements, HeapObject::kMapOffset));
-  __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
-  __ cmp(t1, ip);
-  __ b(ne, miss);
-}


 // Helper function used from LoadIC GenerateNormal.
@@ -328,29 +286,20 @@


 void LoadIC::GenerateNormal(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- r2    : name
-  //  -- lr    : return address
-  //  -- r1    : receiver
-  // -----------------------------------
-  ASSERT(r1.is(ReceiverRegister()));
-  ASSERT(r2.is(NameRegister()));
+  Register dictionary = r0;
+  ASSERT(!dictionary.is(ReceiverRegister()));
+  ASSERT(!dictionary.is(NameRegister()));

-  Label miss, slow;
+  Label slow;

-  GenerateNameDictionaryReceiverCheck(masm, r1, r0, r3, r4, &miss);
-
-  // r0: elements
-  GenerateDictionaryLoad(masm, &slow, r0, r2, r0, r3, r4);
+  __ ldr(dictionary,
+         FieldMemOperand(ReceiverRegister(), JSObject::kPropertiesOffset));
+ GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), r0, r3, r4);
   __ Ret();

   // Dictionary load failed, go slow (but don't miss).
   __ bind(&slow);
   GenerateRuntimeGetProperty(masm);
-
-  // Cache miss: Jump to runtime.
-  __ bind(&miss);
-  GenerateMiss(masm);
 }


@@ -1162,13 +1111,14 @@
   Register receiver = ReceiverRegister();
   Register name = NameRegister();
   Register value = ValueRegister();
+  Register dictionary = r3;
   ASSERT(receiver.is(r1));
   ASSERT(name.is(r2));
   ASSERT(value.is(r0));

-  GenerateNameDictionaryReceiverCheck(masm, receiver, r3, r4, r5, &miss);
+ __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset));

-  GenerateDictionaryStore(masm, &miss, r3, name, value, r4, r5);
+  GenerateDictionaryStore(masm, &miss, dictionary, name, value, r4, r5);
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->store_normal_hit(),
                       1, r4, r5);
=======================================
--- /branches/bleeding_edge/src/arm64/ic-arm64.cc Mon Jul 14 20:43:41 2014 UTC +++ /branches/bleeding_edge/src/arm64/ic-arm64.cc Tue Jul 15 08:07:25 2014 UTC
@@ -32,51 +32,6 @@
   __ Ccmp(type, JS_GLOBAL_PROXY_TYPE, ZFlag, ne);
   __ B(eq, global_object);
 }
-
-
-// Generated code falls through if the receiver is a regular non-global
-// JS object with slow properties and no interceptors.
-//
-// "receiver" holds the receiver on entry and is unchanged.
-// "elements" holds the property dictionary on fall through.
-static void GenerateNameDictionaryReceiverCheck(MacroAssembler* masm,
-                                                Register receiver,
-                                                Register elements,
-                                                Register scratch0,
-                                                Register scratch1,
-                                                Label* miss) {
-  ASSERT(!AreAliased(receiver, elements, scratch0, scratch1));
-
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, miss);
-
-  // Check that the receiver is a valid JS object.
-  // Let t be the object instance type, we want:
-  //   FIRST_SPEC_OBJECT_TYPE <= t <= LAST_SPEC_OBJECT_TYPE.
-  // Since LAST_SPEC_OBJECT_TYPE is the last possible instance type we only
-  // check the lower bound.
-  STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
-
-  __ JumpIfObjectType(receiver, scratch0, scratch1, FIRST_SPEC_OBJECT_TYPE,
-                      miss, lt);
-
- // scratch0 now contains the map of the receiver and scratch1 the object type.
-  Register map = scratch0;
-  Register type = scratch1;
-
-  // Check if the receiver is a global JS object.
-  GenerateGlobalInstanceTypeCheck(masm, type, miss);
-
-  // Check that the object does not require access checks.
-  __ Ldrb(scratch1, FieldMemOperand(map, Map::kBitFieldOffset));
-  __ Tbnz(scratch1, Map::kIsAccessCheckNeeded, miss);
-  __ Tbnz(scratch1, Map::kHasNamedInterceptor, miss);
-
-  // Check that the properties dictionary is valid.
-  __ Ldr(elements, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
-  __ Ldr(scratch1, FieldMemOperand(elements, HeapObject::kMapOffset));
-  __ JumpIfNotRoot(scratch1, Heap::kHashTableMapRootIndex, miss);
-}


 // Helper function used from LoadIC GenerateNormal.
@@ -424,28 +379,19 @@


 void LoadIC::GenerateNormal(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- x2    : name
-  //  -- lr    : return address
-  //  -- x1    : receiver
-  // -----------------------------------
-  ASSERT(x1.is(ReceiverRegister()));
-  ASSERT(x2.is(NameRegister()));
-  Label miss, slow;
+  Register dictionary = x0;
+  ASSERT(!dictionary.is(ReceiverRegister()));
+  ASSERT(!dictionary.is(NameRegister()));
+  Label slow;

-  GenerateNameDictionaryReceiverCheck(masm, x1, x0, x3, x4, &miss);
-
-  // x0 now holds the property dictionary.
-  GenerateDictionaryLoad(masm, &slow, x0, x2, x0, x3, x4);
+  __ Ldr(dictionary,
+         FieldMemOperand(ReceiverRegister(), JSObject::kPropertiesOffset));
+ GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), x0, x3, x4);
   __ Ret();

   // Dictionary load failed, go slow (but don't miss).
   __ Bind(&slow);
   GenerateRuntimeGetProperty(masm);
-
-  // Cache miss: Jump to runtime.
-  __ Bind(&miss);
-  GenerateMiss(masm);
 }


@@ -1203,8 +1149,7 @@
   Register dictionary = x3;
   ASSERT(!AreAliased(value, receiver, name, x3, x4, x5));

-  GenerateNameDictionaryReceiverCheck(
-      masm, receiver, dictionary, x4, x5, &miss);
+ __ Ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset));

   GenerateDictionaryStore(masm, &miss, dictionary, name, value, x4, x5);
   Counters* counters = masm->isolate()->counters();
=======================================
--- /branches/bleeding_edge/src/ia32/ic-ia32.cc Mon Jul 14 20:43:41 2014 UTC
+++ /branches/bleeding_edge/src/ia32/ic-ia32.cc Tue Jul 15 08:07:25 2014 UTC
@@ -33,45 +33,6 @@
   __ cmp(type, JS_GLOBAL_PROXY_TYPE);
   __ j(equal, global_object);
 }
-
-
-// Generated code falls through if the receiver is a regular non-global
-// JS object with slow properties and no interceptors.
-static void GenerateNameDictionaryReceiverCheck(MacroAssembler* masm,
-                                                Register receiver,
-                                                Register r0,
-                                                Register r1,
-                                                Label* miss) {
-  // Register usage:
-  //   receiver: holds the receiver on entry and is unchanged.
-  //   r0: used to hold receiver instance type.
-  //       Holds the property dictionary on fall through.
-  //   r1: used to hold receivers map.
-
-  // Check that the receiver isn't a smi.
-  __ JumpIfSmi(receiver, miss);
-
-  // Check that the receiver is a valid JS object.
-  __ mov(r1, FieldOperand(receiver, HeapObject::kMapOffset));
-  __ movzx_b(r0, FieldOperand(r1, Map::kInstanceTypeOffset));
-  __ cmp(r0, FIRST_SPEC_OBJECT_TYPE);
-  __ j(below, miss);
-
-  // If this assert fails, we have to check upper bound too.
-  STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
-
-  GenerateGlobalInstanceTypeCheck(masm, r0, miss);
-
-  // Check for non-global object that requires access check.
-  __ test_b(FieldOperand(r1, Map::kBitFieldOffset),
-            (1 << Map::kIsAccessCheckNeeded) |
-            (1 << Map::kHasNamedInterceptor));
-  __ j(not_zero, miss);
-
-  __ mov(r0, FieldOperand(receiver, JSObject::kPropertiesOffset));
-  __ CheckMap(r0, masm->isolate()->factory()->hash_table_map(), miss,
-              DONT_DO_SMI_CHECK);
-}


 // Helper function used to load a property from a dictionary backing
@@ -942,30 +903,21 @@


 void LoadIC::GenerateNormal(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- ecx    : name
-  //  -- edx    : receiver
-  //  -- esp[0] : return address
-  // -----------------------------------
-  ASSERT(edx.is(ReceiverRegister()));
-  ASSERT(ecx.is(NameRegister()));
+  Register dictionary = eax;
+  ASSERT(!dictionary.is(ReceiverRegister()));
+  ASSERT(!dictionary.is(NameRegister()));

-  Label miss, slow;
+  Label slow;

-  GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss);
-
-  // eax: elements
-  // Search the dictionary placing the result in eax.
-  GenerateDictionaryLoad(masm, &slow, eax, ecx, edi, ebx, eax);
+  __ mov(dictionary,
+         FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset));
+  GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), edi, ebx,
+                         eax);
   __ ret(0);

   // Dictionary load failed, go slow (but don't miss).
   __ bind(&slow);
   GenerateRuntimeGetProperty(masm);
-
-  // Cache miss: Jump to runtime.
-  __ bind(&miss);
-  GenerateMiss(masm);
 }


@@ -1094,19 +1046,20 @@


 void StoreIC::GenerateNormal(MacroAssembler* masm) {
-  // Return address is on the stack.
-  Label miss, restore_miss;
+  Label restore_miss;
   Register receiver = ReceiverRegister();
   Register name = NameRegister();
   Register value = ValueRegister();
+  Register dictionary = ebx;

-  GenerateNameDictionaryReceiverCheck(masm, receiver, ebx, edi, &miss);
+  __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset));

   // A lot of registers are needed for storing to slow case
   // objects. Push and restore receiver but rely on
   // GenerateDictionaryStore preserving the value and name.
   __ push(receiver);
- GenerateDictionaryStore(masm, &restore_miss, ebx, name, value, receiver, edi);
+  GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value,
+                          receiver, edi);
   __ Drop(1);
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->store_normal_hit(), 1);
@@ -1114,8 +1067,6 @@

   __ bind(&restore_miss);
   __ pop(receiver);
-
-  __ bind(&miss);
   __ IncrementCounter(counters->store_normal_miss(), 1);
   GenerateMiss(masm);
 }
=======================================
--- /branches/bleeding_edge/src/x64/ic-x64.cc   Mon Jul 14 20:43:41 2014 UTC
+++ /branches/bleeding_edge/src/x64/ic-x64.cc   Tue Jul 15 08:07:25 2014 UTC
@@ -33,46 +33,6 @@
   __ cmpb(type, Immediate(JS_GLOBAL_PROXY_TYPE));
   __ j(equal, global_object);
 }
-
-
-// Generated code falls through if the receiver is a regular non-global
-// JS object with slow properties and no interceptors.
-static void GenerateNameDictionaryReceiverCheck(MacroAssembler* masm,
-                                                Register receiver,
-                                                Register r0,
-                                                Register r1,
-                                                Label* miss) {
-  // Register usage:
-  //   receiver: holds the receiver on entry and is unchanged.
-  //   r0: used to hold receiver instance type.
-  //       Holds the property dictionary on fall through.
-  //   r1: used to hold receivers map.
-
-  __ JumpIfSmi(receiver, miss);
-
-  // Check that the receiver is a valid JS object.
-  __ movp(r1, FieldOperand(receiver, HeapObject::kMapOffset));
-  __ movb(r0, FieldOperand(r1, Map::kInstanceTypeOffset));
-  __ cmpb(r0, Immediate(FIRST_SPEC_OBJECT_TYPE));
-  __ j(below, miss);
-
-  // If this assert fails, we have to check upper bound too.
-  STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
-
-  GenerateGlobalInstanceTypeCheck(masm, r0, miss);
-
-  // Check for non-global object that requires access check.
-  __ testb(FieldOperand(r1, Map::kBitFieldOffset),
-           Immediate((1 << Map::kIsAccessCheckNeeded) |
-                     (1 << Map::kHasNamedInterceptor)));
-  __ j(not_zero, miss);
-
-  __ movp(r0, FieldOperand(receiver, JSObject::kPropertiesOffset));
-  __ CompareRoot(FieldOperand(r0, HeapObject::kMapOffset),
-                 Heap::kHashTableMapRootIndex);
-  __ j(not_equal, miss);
-}
-


// Helper function used to load a property from a dictionary backing storage.
@@ -959,29 +919,21 @@


 void LoadIC::GenerateNormal(MacroAssembler* masm) {
-  // ----------- S t a t e -------------
-  //  -- rdx    : receiver
-  //  -- rcx    : name
-  //  -- rsp[0] : return address
-  // -----------------------------------
-  ASSERT(rdx.is(ReceiverRegister()));
-  ASSERT(rcx.is(NameRegister()));
-  Label miss, slow;
+  Register dictionary = rax;
+  ASSERT(!dictionary.is(ReceiverRegister()));
+  ASSERT(!dictionary.is(NameRegister()));

-  GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss);
+  Label slow;

-  //  rax: elements
-  // Search the dictionary placing the result in rax.
-  GenerateDictionaryLoad(masm, &slow, rax, rcx, rbx, rdi, rax);
+  __ movp(dictionary,
+          FieldOperand(ReceiverRegister(), JSObject::kPropertiesOffset));
+  GenerateDictionaryLoad(masm, &slow, dictionary, NameRegister(), rbx, rdi,
+                         rax);
   __ ret(0);

   // Dictionary load failed, go slow (but don't miss).
   __ bind(&slow);
   GenerateRuntimeGetProperty(masm);
-
-  // Cache miss: Jump to runtime.
-  __ bind(&miss);
-  GenerateMiss(masm);
 }


@@ -1125,16 +1077,15 @@


 void StoreIC::GenerateNormal(MacroAssembler* masm) {
-  // Return address is on the stack.
   Register receiver = ReceiverRegister();
   Register name = NameRegister();
   Register value = ValueRegister();
+  Register dictionary = rbx;

   Label miss;

-  GenerateNameDictionaryReceiverCheck(masm, receiver, rbx, rdi, &miss);
-
-  GenerateDictionaryStore(masm, &miss, rbx, name, value, r8, r9);
+  __ movp(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset));
+  GenerateDictionaryStore(masm, &miss, dictionary, name, value, r8, r9);
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->store_normal_hit(), 1);
   __ ret(0);

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to