Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Unified Diff: src/arm/stub-cache-arm.cc

Issue 196024: Last step in allocating objects in generated code on ARM (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/stub-cache-arm.cc
===================================================================
--- src/arm/stub-cache-arm.cc (revision 2825)
+++ src/arm/stub-cache-arm.cc (working copy)
@@ -1344,7 +1344,142 @@
Object* ConstructStubCompiler::CompileConstructStub(
SharedFunctionInfo* shared) {
- // Not implemented yet - just jump to generic stub.
+ // ----------- S t a t e -------------
+ // -- r0 : argc
+ // -- r1 : constructor
+ // -- lr : return address
+ // -- [sp] : last argument
+ // -----------------------------------
+ Label generic_stub_call;
+
+ // Use r7 for holding undefined which is used in several places below.
+ __ LoadRoot(r7, Heap::kUndefinedValueRootIndex);
+
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ // Check to see whether there are any break points in the function code. If
+ // there are jump to the generic constructor stub which calls the actual
+ // code for the function thereby hitting the break points.
+ __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
+ __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kDebugInfoOffset));
+ __ cmp(r2, r7);
Erik Corry 2009/09/07 10:21:45 I'd like to see a performance bot run with and wit
Søren Thygesen Gjesse 2009/09/07 10:26:43 I will do that.
+ __ b(ne, &generic_stub_call);
+#endif
+
+ // Load the initial map and verify that it is in fact a map.
+ // r1: constructor function
+ // r7: undefined
+ __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
+ __ tst(r2, Operand(kSmiTagMask));
+ __ b(eq, &generic_stub_call);
+ __ CompareObjectType(r2, r3, r4, MAP_TYPE);
+ __ b(ne, &generic_stub_call);
+
+#ifdef DEBUG
+ // Cannot construct functions this way.
+ // r0: argc
+ // r1: constructor function
+ // r2: initial map
+ // r7: undefined
+ __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE);
+ __ Check(ne, "Function constructed by construct stub.");
+#endif
+
+ // Now allocate the JSObject in new space.
+ // r0: argc
+ // r1: constructor function
+ // r2: initial map
+ // r7: undefined
+ __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset));
+ // Make sure that the maximum heap object size will never cause us
+ // problem here, because it is always greater than the maximum
+ // instance size that can be represented in a byte.
+ ASSERT(Heap::MaxObjectSizeInPagedSpace() >= JSObject::kMaxInstanceSize);
Erik Corry 2009/09/07 10:21:45 Unnecessary assert.
Søren Thygesen Gjesse 2009/09/07 10:26:43 Done.
+ __ AllocateObjectInNewSpace(r3,
+ r4,
+ r5,
+ r6,
+ &generic_stub_call,
+ NO_ALLOCATION_FLAGS);
+
+ // Allocated the JSObject, now initialize the fields. Map is set to initial
+ // map and properties and elements are set to empty fixed array.
+ // r0: argc
+ // r1: constructor function
+ // r2: initial map
+ // r3: object size (in words)
+ // r4: JSObject (not tagged)
+ // r7: undefined
+ __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex);
+ __ mov(r5, r4);
+ ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
+ __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
+ ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
+ __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
+ ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset);
+ __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
+
+ // Calculate the location of the first argument. The stack contains only the
+ // argc arguments.
+ __ add(r1, sp, Operand(r0, LSL, kPointerSizeLog2));
+
+ // Fill all the in-object properties with undefined.
+ // r0: argc
+ // r1: first argument
+ // r3: object size (in words)
+ // r4: JSObject (not tagged)
+ // r5: First in-object property of JSObject (not tagged)
+ // r7: undefined
+ // Fill the initialized properties with a constant value or a passed argument
+ // depending on the this.x = ...; assignment in the function.
+ for (int i = 0; i < shared->this_property_assignments_count(); i++) {
+ if (shared->IsThisPropertyAssignmentArgument(i)) {
+ Label not_passed, next;
+ // Check if the argument assigned to the property is actually passed.
+ int arg_number = shared->GetThisPropertyAssignmentArgument(i);
+ __ cmp(r0, Operand(arg_number));
+ __ b(le, &not_passed);
+ // Argument passed - find it on the stack.
+ __ ldr(r2, MemOperand(r1, (arg_number + 1) * -kPointerSize));
+ __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
+ __ b(&next);
+ __ bind(&not_passed);
+ // Set the property to undefined.
+ __ str(r7, MemOperand(r5, kPointerSize, PostIndex));
+ __ bind(&next);
+ } else {
+ // Set the property to the constant value.
+ Handle<Object> constant(shared->GetThisPropertyAssignmentConstant(i));
+ __ mov(r2, Operand(constant));
+ __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
+ }
+ }
+
+ // Fill the unused in-object property fields with undefined.
+ for (int i = shared->this_property_assignments_count();
+ i < shared->CalculateInObjectProperties();
+ i++) {
+ __ str(r7, MemOperand(r5, kPointerSize, PostIndex));
+ }
+
+ // r0: argc
+ // r4: JSObject (not tagged)
+ // Move argc to r1 and the JSObject to return to r0 and tag it.
+ __ mov(r1, r0);
+ __ mov(r0, r4);
+ __ orr(r0, r0, Operand(kHeapObjectTag));
+
+ // r0: JSObject
+ // r1: argc
+ // Remove caller arguments and receiver from the stack and return.
+ __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2));
+ __ add(sp, sp, Operand(kPointerSize));
+ __ IncrementCounter(&Counters::constructed_objects, 1, r1, r2);
+ __ IncrementCounter(&Counters::constructed_objects_stub, 1, r1, r2);
+ __ Jump(lr);
+
+ // Jump to the generic stub in case the specialized code cannot handle the
+ // construction.
+ __ bind(&generic_stub_call);
Code* code = Builtins::builtin(Builtins::JSConstructStubGeneric);
Handle<Code> generic_construct_stub(code);
__ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698