Revision: 14173
Author:   [email protected]
Date:     Tue Apr  9 01:09:05 2013
Log: Always check global property cells for readonliness before storing.
Add check when the global object is the last in the chain.

Review URL: https://chromiumcodereview.appspot.com/13730002
http://code.google.com/p/v8/source/detail?r=14173

Added:
 /branches/bleeding_edge/test/mjsunit/regress/readonly5.js
Modified:
 /branches/bleeding_edge/src/arm/stub-cache-arm.cc
 /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
 /branches/bleeding_edge/src/x64/stub-cache-x64.cc

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/readonly5.js Tue Apr 9 01:09:05 2013
@@ -0,0 +1,68 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+this.__proto__ = null;
+this.x = 10;
+delete this.x;
+
+function s(v) {
+  return v.x = 1;
+}
+
+function s_strict(v) {
+  "use strict";
+  return v.x = 1;
+}
+
+function c() {
+  var o = {__proto__:this};
+  return o;
+}
+
+var o1 = c();
+var o2 = c();
+var o1_strict = c();
+var o2_strict = c();
+var o3 = c();
+var o4 = c();
+
+// Initialize the store IC.
+s(o1);
+s(o2);
+s_strict(o1_strict);
+s_strict(o2_strict);
+
+Object.defineProperty(this, "x", {writable:false, configurable:true});
+
+// Verify that directly setting x fails.
+o3.x = 1;
+assertEquals(undefined, o3.x);
+
+// Verify that setting x through the IC fails.
+assertThrows("s_strict(o4)", TypeError);
+s(o4);
+assertEquals(undefined, o4.x);
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Sat Apr 6 21:34:20 2013 +++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Tue Apr 9 01:09:05 2013
@@ -415,6 +415,26 @@
   __ mov(r0, scratch1);
   __ Ret();
 }
+
+
+// Generate code to check that a global property cell is empty. Create
+// the property cell at compilation time if no cell exists for the
+// property.
+static void GenerateCheckPropertyCell(MacroAssembler* masm,
+                                      Handle<GlobalObject> global,
+                                      Handle<Name> name,
+                                      Register scratch,
+                                      Label* miss) {
+  Handle<JSGlobalPropertyCell> cell =
+      GlobalObject::EnsurePropertyCell(global, name);
+  ASSERT(cell->value()->IsTheHole());
+  __ mov(scratch, Operand(cell));
+  __ ldr(scratch,
+         FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
+  __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+  __ cmp(scratch, ip);
+  __ b(ne, miss);
+}


 // Generate StoreField code, value is passed in r0 register.
@@ -466,12 +486,18 @@
     // 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
     // holder.
-    if (lookup->holder() == *object &&
-        !holder->HasFastProperties() &&
-        !holder->IsJSGlobalProxy() &&
-        !holder->IsJSGlobalObject()) {
-      GenerateDictionaryNegativeLookup(
-          masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
+    if (lookup->holder() == *object) {
+      if (holder->IsJSGlobalObject()) {
+        GenerateCheckPropertyCell(
+            masm,
+            Handle<GlobalObject>(GlobalObject::cast(holder)),
+            name,
+            scratch1,
+            miss_restore_name);
+ } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
+        GenerateDictionaryNegativeLookup(
+            masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
+      }
     }
   }

@@ -924,26 +950,6 @@
   Register name_;
   Code::ExtraICState extra_ic_state_;
 };
-
-
-// Generate code to check that a global property cell is empty. Create
-// the property cell at compilation time if no cell exists for the
-// property.
-static void GenerateCheckPropertyCell(MacroAssembler* masm,
-                                      Handle<GlobalObject> global,
-                                      Handle<Name> name,
-                                      Register scratch,
-                                      Label* miss) {
-  Handle<JSGlobalPropertyCell> cell =
-      GlobalObject::EnsurePropertyCell(global, name);
-  ASSERT(cell->value()->IsTheHole());
-  __ mov(scratch, Operand(cell));
-  __ ldr(scratch,
-         FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset));
-  __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
-  __ cmp(scratch, ip);
-  __ b(ne, miss);
-}


// Calls GenerateCheckPropertyCell for each global object in the prototype chain
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Fri Apr 5 08:17:44 2013 +++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Tue Apr 9 01:09:05 2013
@@ -724,6 +724,29 @@
     __ mov(this->name(), Immediate(name));
   }
 }
+
+
+// Generate code to check that a global property cell is empty. Create
+// the property cell at compilation time if no cell exists for the
+// property.
+static void GenerateCheckPropertyCell(MacroAssembler* masm,
+                                      Handle<GlobalObject> global,
+                                      Handle<Name> name,
+                                      Register scratch,
+                                      Label* miss) {
+  Handle<JSGlobalPropertyCell> cell =
+      GlobalObject::EnsurePropertyCell(global, name);
+  ASSERT(cell->value()->IsTheHole());
+  Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value();
+  if (Serializer::enabled()) {
+    __ mov(scratch, Immediate(cell));
+    __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
+           Immediate(the_hole));
+  } else {
+    __ cmp(Operand::Cell(cell), Immediate(the_hole));
+  }
+  __ j(not_equal, miss);
+}


 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
@@ -771,12 +794,18 @@
     // 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
     // holder.
-    if (lookup->holder() == *object &&
-        !holder->HasFastProperties() &&
-        !holder->IsJSGlobalProxy() &&
-        !holder->IsJSGlobalObject()) {
-      GenerateDictionaryNegativeLookup(
-          masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
+    if (lookup->holder() == *object) {
+      if (holder->IsJSGlobalObject()) {
+        GenerateCheckPropertyCell(
+            masm,
+            Handle<GlobalObject>(GlobalObject::cast(holder)),
+            name,
+            scratch1,
+            miss_restore_name);
+ } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
+        GenerateDictionaryNegativeLookup(
+            masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
+      }
     }
   }

@@ -862,29 +891,6 @@
   ASSERT(value_reg.is(eax));
   __ ret(0);
 }
-
-
-// Generate code to check that a global property cell is empty. Create
-// the property cell at compilation time if no cell exists for the
-// property.
-static void GenerateCheckPropertyCell(MacroAssembler* masm,
-                                      Handle<GlobalObject> global,
-                                      Handle<Name> name,
-                                      Register scratch,
-                                      Label* miss) {
-  Handle<JSGlobalPropertyCell> cell =
-      GlobalObject::EnsurePropertyCell(global, name);
-  ASSERT(cell->value()->IsTheHole());
-  Handle<Oddball> the_hole = masm->isolate()->factory()->the_hole_value();
-  if (Serializer::enabled()) {
-    __ mov(scratch, Immediate(cell));
-    __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
-           Immediate(the_hole));
-  } else {
-    __ cmp(Operand::Cell(cell), Immediate(the_hole));
-  }
-  __ j(not_equal, miss);
-}


// Calls GenerateCheckPropertyCell for each global object in the prototype chain
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Fri Apr 5 08:17:44 2013 +++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Tue Apr 9 01:09:05 2013
@@ -710,6 +710,24 @@
     __ Move(this->name(), name);
   }
 }
+
+
+// Generate code to check that a global property cell is empty. Create
+// the property cell at compilation time if no cell exists for the
+// property.
+static void GenerateCheckPropertyCell(MacroAssembler* masm,
+                                      Handle<GlobalObject> global,
+                                      Handle<Name> name,
+                                      Register scratch,
+                                      Label* miss) {
+  Handle<JSGlobalPropertyCell> cell =
+      GlobalObject::EnsurePropertyCell(global, name);
+  ASSERT(cell->value()->IsTheHole());
+  __ Move(scratch, cell);
+  __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
+         masm->isolate()->factory()->the_hole_value());
+  __ j(not_equal, miss);
+}


 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
@@ -756,12 +774,18 @@
     // 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
     // holder.
-    if (lookup->holder() == *object &&
-        !holder->HasFastProperties() &&
-        !holder->IsJSGlobalProxy() &&
-        !holder->IsJSGlobalObject()) {
-      GenerateDictionaryNegativeLookup(
-          masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
+    if (lookup->holder() == *object) {
+      if (holder->IsJSGlobalObject()) {
+        GenerateCheckPropertyCell(
+            masm,
+            Handle<GlobalObject>(GlobalObject::cast(holder)),
+            name,
+            scratch1,
+            miss_restore_name);
+ } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) {
+        GenerateDictionaryNegativeLookup(
+            masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
+      }
     }
   }

@@ -840,24 +864,6 @@
   ASSERT(value_reg.is(rax));
   __ ret(0);
 }
-
-
-// Generate code to check that a global property cell is empty. Create
-// the property cell at compilation time if no cell exists for the
-// property.
-static void GenerateCheckPropertyCell(MacroAssembler* masm,
-                                      Handle<GlobalObject> global,
-                                      Handle<Name> name,
-                                      Register scratch,
-                                      Label* miss) {
-  Handle<JSGlobalPropertyCell> cell =
-      GlobalObject::EnsurePropertyCell(global, name);
-  ASSERT(cell->value()->IsTheHole());
-  __ Move(scratch, cell);
-  __ Cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
-         masm->isolate()->factory()->the_hole_value());
-  __ j(not_equal, miss);
-}


// Calls GenerateCheckPropertyCell for each global object in the prototype chain

--
--
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/groups/opt_out.


Reply via email to