MIPS: Implement inlined object allocation in Crankshaft.
authormstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 1 Mar 2012 12:38:58 +0000 (12:38 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 1 Mar 2012 12:38:58 +0000 (12:38 +0000)
Port r10881 (0d25c61e).

Original commit message:

Generates inlined code for object allocation specific to the initial map
of the given constructor function. Also forces completion of inobject
slack tracking while crankshafting to finalize instance size of these
objects.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9569008
Patch from Daniel Kalmar <kalmard@homejinni.com>.

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

src/flag-definitions.h
src/mips/lithium-codegen-mips.cc
src/mips/lithium-mips.cc
src/mips/lithium-mips.h

index 9ab8ab5048e79352bd80bebdfa0c704449afa570..4f4ad6a84b4e2eb11757304126839772099f4807 100644 (file)
@@ -168,7 +168,7 @@ DEFINE_bool(use_osr, true, "use on-stack replacement")
 DEFINE_bool(trace_osr, false, "trace on-stack replacement")
 DEFINE_int(stress_runs, 0, "number of stress runs")
 DEFINE_bool(optimize_closures, true, "optimize closures")
-DEFINE_bool(inline_construct, false, "inline constructor calls")
+DEFINE_bool(inline_construct, true, "inline constructor calls")
 DEFINE_int(loop_weight, 1, "loop weight for representation inference")
 
 DEFINE_bool(optimize_for_in, true,
index 25754c5e5423946741848142d2b51a1d7c51d18a..a463cd3257e526bc8230d57fc0494526107a8bea 100644 (file)
@@ -4243,9 +4243,45 @@ void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
 
   DeferredAllocateObject* deferred = new DeferredAllocateObject(this, instr);
 
-  // TODO(mstarzinger): Implement inlined version instead of jumping to
-  // deferred runtime call.
-  __ jmp(deferred->entry());
+  Register result = ToRegister(instr->result());
+  Register scratch = ToRegister(instr->TempAt(0));
+  Register scratch2 = ToRegister(instr->TempAt(1));
+  Handle<JSFunction> constructor = instr->hydrogen()->constructor();
+  Handle<Map> initial_map(constructor->initial_map());
+  int instance_size = initial_map->instance_size();
+  ASSERT(initial_map->pre_allocated_property_fields() +
+         initial_map->unused_property_fields() -
+         initial_map->inobject_properties() == 0);
+
+  // Allocate memory for the object.  The initial map might change when
+  // the constructor's prototype changes, but instance size and property
+  // counts remain unchanged (if slack tracking finished).
+  ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress());
+  __ AllocateInNewSpace(instance_size,
+                        result,
+                        scratch,
+                        scratch2,
+                        deferred->entry(),
+                        TAG_OBJECT);
+
+  // Load the initial map.
+  Register map = scratch;
+  __ LoadHeapObject(map, constructor);
+  __ lw(map, FieldMemOperand(map, JSFunction::kPrototypeOrInitialMapOffset));
+
+  // Initialize map and fields of the newly allocated object.
+  ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
+  __ sw(map, FieldMemOperand(result, JSObject::kMapOffset));
+  __ LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex);
+  __ sw(scratch, FieldMemOperand(result, JSObject::kElementsOffset));
+  __ sw(scratch, FieldMemOperand(result, JSObject::kPropertiesOffset));
+  if (initial_map->inobject_properties() != 0) {
+    __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
+    for (int i = 0; i < initial_map->inobject_properties(); i++) {
+      int property_offset = JSObject::kHeaderSize + i * kPointerSize;
+      __ sw(scratch, FieldMemOperand(result, property_offset));
+    }
+  }
 
   __ bind(deferred->exit());
 }
index b18a85f3d9f25470ffa880125aca11ae17856c78..9ec1c1b8a7877ca6a13ec17ac0392980c287ae43 100644 (file)
@@ -2126,7 +2126,8 @@ LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
 
 
 LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) {
-  LAllocateObject* result = new(zone()) LAllocateObject();
+  LAllocateObject* result = new(zone()) LAllocateObject(
+      TempRegister(), TempRegister());
   return AssignPointerMap(DefineAsRegister(result));
 }
 
index cc9d3b107816a22082c253e35da2b304cb193b87..2128ce3e9eb127eb049d7ba773f5dbcaa340b96e 100644 (file)
@@ -1922,8 +1922,13 @@ class LClampTToUint8: public LTemplateInstruction<1, 1, 1> {
 };
 
 
-class LAllocateObject: public LTemplateInstruction<1, 0, 0> {
+class LAllocateObject: public LTemplateInstruction<1, 0, 2> {
  public:
+  LAllocateObject(LOperand* temp1, LOperand* temp2) {
+    temps_[0] = temp1;
+    temps_[1] = temp2;
+  }
+
   DECLARE_CONCRETE_INSTRUCTION(AllocateObject, "allocate-object")
   DECLARE_HYDROGEN_ACCESSOR(AllocateObject)
 };