Handle pre-allocated properties when copying map.
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 26 Aug 2009 11:03:07 +0000 (11:03 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 26 Aug 2009 11:03:07 +0000 (11:03 +0000)
When copying a map always set the descriptor array to describe the pre-allocated properties, even when descriptors are to be dropped.

Added a test which otherwise failed with an assert on ARM in debug mode. The reason for it only surfasing on ARM is that the NewObject runtime function is always used for allocating new JSObjects on ARM.

This change includes a few parts of http://codereview.chromium.org/174392 needed to trigger the error.
Review URL: http://codereview.chromium.org/173469

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

src/compiler.cc
src/objects-debug.cc
src/objects.cc
src/runtime.cc
test/mjsunit/simple-constructor.js

index feff492..15f6479 100644 (file)
@@ -425,6 +425,13 @@ bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared,
   // Set the expected number of properties for instances.
   SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
 
+  // Set the optimication hints after performing lazy compilation, as these are
+  // not set when the function is set up as a lazily compiled function.
+  shared->SetThisPropertyAssignmentsInfo(
+      lit->has_only_this_property_assignments(),
+      lit->has_only_simple_this_property_assignments(),
+      *lit->this_property_assignments());
+
   // Check the function has compiled code.
   ASSERT(shared->is_compiled());
   return true;
index f713171..ef4aae5 100644 (file)
@@ -463,6 +463,8 @@ void Map::MapPrint() {
   PrintF(" - type: %s\n", TypeToString(instance_type()));
   PrintF(" - instance size: %d\n", instance_size());
   PrintF(" - inobject properties: %d\n", inobject_properties());
+  PrintF(" - pre-allocated property fields: %d\n",
+      pre_allocated_property_fields());
   PrintF(" - unused property fields: %d\n", unused_property_fields());
   if (is_hidden_prototype()) {
     PrintF(" - hidden_prototype\n");
index e4a3a67..225d37f 100644 (file)
@@ -2923,6 +2923,17 @@ Object* Map::CopyDropDescriptors() {
   // Please note instance_type and instance_size are set when allocated.
   Map::cast(result)->set_inobject_properties(inobject_properties());
   Map::cast(result)->set_unused_property_fields(unused_property_fields());
+
+  // If the map has pre-allocated properties always start out with a descriptor
+  // array describing these properties.
+  if (pre_allocated_property_fields() > 0) {
+    ASSERT(constructor()->IsJSFunction());
+    JSFunction* ctor = JSFunction::cast(constructor());
+    Map::cast(result)->set_instance_descriptors(
+        ctor->initial_map()->instance_descriptors());
+    Map::cast(result)->set_pre_allocated_property_fields(
+        pre_allocated_property_fields());
+  }
   Map::cast(result)->set_bit_field(bit_field());
   Map::cast(result)->set_bit_field2(bit_field2());
   Map::cast(result)->ClearCodeCache();
@@ -4800,7 +4811,6 @@ void SharedFunctionInfo::SetThisPropertyAssignmentsInfo(
     bool only_this_property_assignments,
     bool only_simple_this_property_assignments,
     FixedArray* assignments) {
-  ASSERT(this_property_assignments()->IsUndefined());
   set_compiler_hints(BooleanBit::set(compiler_hints(),
                                      kHasOnlyThisPropertyAssignments,
                                      only_this_property_assignments));
index 845ac63..a6c30b3 100644 (file)
@@ -4373,6 +4373,13 @@ static Object* Runtime_NewObject(Arguments args) {
     }
   }
 
+  // The function should be compiled for the optimization hints to be available.
+  if (!function->shared()->is_compiled()) {
+     CompileLazyShared(Handle<SharedFunctionInfo>(function->shared()),
+                                                  CLEAR_EXCEPTION,
+                                                  0);
+  }
+
   bool first_allocation = !function->has_initial_map();
   Handle<JSObject> result = Factory::NewJSObject(function);
   if (first_allocation) {
index b26d651..557c699 100755 (executable)
@@ -76,3 +76,20 @@ o4_1_1 = new f4(1);
 o4_1_2 = new f4(1);
 assertArrayEquals(["x", "y"], props(o4_1_1));
 assertArrayEquals(["x", "y"], props(o4_1_2));
+
+function g(){
+  this.x=1
+}
+
+o = new g();
+assertEquals(1, o.x);
+o = new g();
+assertEquals(1, o.x);
+g.prototype = {y:2}
+o = new g();
+assertEquals(1, o.x);
+assertEquals(2, o.y);
+o = new g();
+assertEquals(1, o.x);
+assertEquals(2, o.y);
+