@@ -151,158 +151,155 @@ void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
151151 // -- sp[...]: constructor arguments
152152 // -----------------------------------
153153
154+ FrameScope scope (masm, StackFrame::MANUAL);
154155 // Enter a construct frame.
155- {
156- FrameAndConstantPoolScope scope (masm, StackFrame::CONSTRUCT);
157- Label post_instantiation_deopt_entry, not_create_implicit_receiver;
158-
159- // Preserve the incoming parameters on the stack.
160- __ LoadRoot (r4, RootIndex::kTheHoleValue );
161- __ SmiTag (r0);
162- __ Push (cp, r0, r1, r4, r3);
163-
164- // ----------- S t a t e -------------
165- // -- sp[0*kPointerSize]: new target
166- // -- sp[1*kPointerSize]: padding
167- // -- r1 and sp[2*kPointerSize]: constructor function
168- // -- sp[3*kPointerSize]: number of arguments (tagged)
169- // -- sp[4*kPointerSize]: context
170- // -----------------------------------
171-
172- __ ldr (r4, FieldMemOperand (r1, JSFunction::kSharedFunctionInfoOffset ));
173- __ ldr (r4, FieldMemOperand (r4, SharedFunctionInfo::kFlagsOffset ));
174- __ DecodeField<SharedFunctionInfo::FunctionKindBits>(r4);
175- __ JumpIfIsInRange (r4, kDefaultDerivedConstructor , kDerivedConstructor ,
176- ¬_create_implicit_receiver);
177-
178- // If not derived class constructor: Allocate the new receiver object.
179- __ IncrementCounter (masm->isolate ()->counters ()->constructed_objects (), 1 ,
180- r4, r5);
181- __ Call (BUILTIN_CODE (masm->isolate (), FastNewObject),
182- RelocInfo::CODE_TARGET);
183- __ b (&post_instantiation_deopt_entry);
184-
185- // Else: use TheHoleValue as receiver for constructor call
186- __ bind (¬_create_implicit_receiver);
187- __ LoadRoot (r0, RootIndex::kTheHoleValue );
188-
189- // ----------- S t a t e -------------
190- // -- r0: receiver
191- // -- Slot 3 / sp[0*kPointerSize]: new target
192- // -- Slot 2 / sp[1*kPointerSize]: constructor function
193- // -- Slot 1 / sp[2*kPointerSize]: number of arguments (tagged)
194- // -- Slot 0 / sp[3*kPointerSize]: context
195- // -----------------------------------
196- // Deoptimizer enters here.
197- masm->isolate ()->heap ()->SetConstructStubCreateDeoptPCOffset (
198- masm->pc_offset ());
199- __ bind (&post_instantiation_deopt_entry);
200-
201- // Restore new target.
202- __ Pop (r3);
203-
204- // Push the allocated receiver to the stack.
205- __ Push (r0);
206- // We need two copies because we may have to return the original one
207- // and the calling conventions dictate that the called function pops the
208- // receiver. The second copy is pushed after the arguments, we saved in r6
209- // since r0 needs to store the number of arguments before
210- // InvokingFunction.
211- __ mov (r6, r0);
212-
213- // Set up pointer to first argument (skip receiver).
214- __ add (
215- r4, fp,
216- Operand (StandardFrameConstants::kCallerSPOffset + kSystemPointerSize ));
156+ Label post_instantiation_deopt_entry, not_create_implicit_receiver;
157+ __ EnterFrame (StackFrame::CONSTRUCT);
217158
218- // Restore constructor function and argument count .
219- __ ldr (r1, MemOperand (fp, ConstructFrameConstants:: kConstructorOffset ) );
220- __ ldr (r0, MemOperand (fp, ConstructFrameConstants:: kLengthOffset ) );
221- __ SmiUntag (r0 );
159+ // Preserve the incoming parameters on the stack .
160+ __ LoadRoot (r4, RootIndex:: kTheHoleValue );
161+ __ SmiTag (r0);
162+ __ Push (cp, r0, r1, r4, r3 );
222163
223- Label enough_stack_space, stack_overflow;
224- __ StackOverflowCheck (r0, r5, &stack_overflow);
225- __ b (&enough_stack_space);
164+ // ----------- S t a t e -------------
165+ // -- sp[0*kPointerSize]: new target
166+ // -- sp[1*kPointerSize]: padding
167+ // -- r1 and sp[2*kPointerSize]: constructor function
168+ // -- sp[3*kPointerSize]: number of arguments (tagged)
169+ // -- sp[4*kPointerSize]: context
170+ // -----------------------------------
226171
227- __ bind (&stack_overflow);
228- // Restore the context from the frame.
229- __ ldr (cp, MemOperand (fp, ConstructFrameConstants::kContextOffset ));
230- __ CallRuntime (Runtime::kThrowStackOverflow );
231- // Unreachable code.
232- __ bkpt (0 );
172+ __ ldr (r4, FieldMemOperand (r1, JSFunction::kSharedFunctionInfoOffset ));
173+ __ ldr (r4, FieldMemOperand (r4, SharedFunctionInfo::kFlagsOffset ));
174+ __ DecodeField<SharedFunctionInfo::FunctionKindBits>(r4);
175+ __ JumpIfIsInRange (r4, kDefaultDerivedConstructor , kDerivedConstructor ,
176+ ¬_create_implicit_receiver);
233177
234- __ bind (&enough_stack_space);
178+ // If not derived class constructor: Allocate the new receiver object.
179+ __ IncrementCounter (masm->isolate ()->counters ()->constructed_objects (), 1 , r4,
180+ r5);
181+ __ Call (BUILTIN_CODE (masm->isolate (), FastNewObject), RelocInfo::CODE_TARGET);
182+ __ b (&post_instantiation_deopt_entry);
235183
236- // TODO(victorgomes): When the arguments adaptor is completely removed, we
237- // should get the formal parameter count and copy the arguments in its
238- // correct position (including any undefined), instead of delaying this to
239- // InvokeFunction.
184+ // Else: use TheHoleValue as receiver for constructor call
185+ __ bind (¬_create_implicit_receiver);
186+ __ LoadRoot (r0, RootIndex::kTheHoleValue );
240187
241- // Copy arguments to the expression stack.
242- __ PushArray (r4, r0, r5);
188+ // ----------- S t a t e -------------
189+ // -- r0: receiver
190+ // -- Slot 3 / sp[0*kPointerSize]: new target
191+ // -- Slot 2 / sp[1*kPointerSize]: constructor function
192+ // -- Slot 1 / sp[2*kPointerSize]: number of arguments (tagged)
193+ // -- Slot 0 / sp[3*kPointerSize]: context
194+ // -----------------------------------
195+ // Deoptimizer enters here.
196+ masm->isolate ()->heap ()->SetConstructStubCreateDeoptPCOffset (
197+ masm->pc_offset ());
198+ __ bind (&post_instantiation_deopt_entry);
199+
200+ // Restore new target.
201+ __ Pop (r3);
202+
203+ // Push the allocated receiver to the stack.
204+ __ Push (r0);
205+ // We need two copies because we may have to return the original one
206+ // and the calling conventions dictate that the called function pops the
207+ // receiver. The second copy is pushed after the arguments, we saved in r6
208+ // since r0 needs to store the number of arguments before
209+ // InvokingFunction.
210+ __ mov (r6, r0);
211+
212+ // Set up pointer to first argument (skip receiver).
213+ __ add (r4, fp,
214+ Operand (StandardFrameConstants::kCallerSPOffset + kSystemPointerSize ));
215+
216+ // Restore constructor function and argument count.
217+ __ ldr (r1, MemOperand (fp, ConstructFrameConstants::kConstructorOffset ));
218+ __ ldr (r0, MemOperand (fp, ConstructFrameConstants::kLengthOffset ));
219+ __ SmiUntag (r0);
243220
244- // Push implicit receiver.
245- __ Push (r6 );
221+ Label stack_overflow;
222+ __ StackOverflowCheck (r0, r5, &stack_overflow );
246223
247- // Call the function.
248- __ InvokeFunctionWithNewTarget (r1, r3, r0, CALL_FUNCTION);
224+ // TODO(victorgomes): When the arguments adaptor is completely removed, we
225+ // should get the formal parameter count and copy the arguments in its
226+ // correct position (including any undefined), instead of delaying this to
227+ // InvokeFunction.
249228
250- // ----------- S t a t e -------------
251- // -- r0: constructor result
252- // -- sp[0*kPointerSize]: implicit receiver
253- // -- sp[1*kPointerSize]: padding
254- // -- sp[2*kPointerSize]: constructor function
255- // -- sp[3*kPointerSize]: number of arguments
256- // -- sp[4*kPointerSize]: context
257- // -----------------------------------
229+ // Copy arguments to the expression stack.
230+ __ PushArray (r4, r0, r5);
258231
259- // Store offset of return address for deoptimizer.
260- masm->isolate ()->heap ()->SetConstructStubInvokeDeoptPCOffset (
261- masm->pc_offset ());
232+ // Push implicit receiver.
233+ __ Push (r6);
262234
263- // Restore the context from the frame .
264- __ ldr (cp, MemOperand (fp, ConstructFrameConstants:: kContextOffset ) );
235+ // Call the function .
236+ __ InvokeFunctionWithNewTarget (r1, r3, r0, CALL_FUNCTION );
265237
266- // If the result is an object (in the ECMA sense), we should get rid
267- // of the receiver and use the result; see ECMA-262 section 13.2.2-7
268- // on page 74.
269- Label use_receiver, do_throw, leave_frame;
238+ // ----------- S t a t e -------------
239+ // -- r0: constructor result
240+ // -- sp[0*kPointerSize]: implicit receiver
241+ // -- sp[1*kPointerSize]: padding
242+ // -- sp[2*kPointerSize]: constructor function
243+ // -- sp[3*kPointerSize]: number of arguments
244+ // -- sp[4*kPointerSize]: context
245+ // -----------------------------------
270246
271- // If the result is undefined, we jump out to using the implicit receiver.
272- __ JumpIfRoot (r0, RootIndex::kUndefinedValue , &use_receiver);
247+ // Store offset of return address for deoptimizer.
248+ masm->isolate ()->heap ()->SetConstructStubInvokeDeoptPCOffset (
249+ masm->pc_offset ());
273250
274- // Otherwise we do a smi check and fall through to check if the return value
275- // is a valid receiver.
251+ // If the result is an object (in the ECMA sense), we should get rid
252+ // of the receiver and use the result; see ECMA-262 section 13.2.2-7
253+ // on page 74.
254+ Label use_receiver, do_throw, leave_and_return, check_receiver;
276255
277- // If the result is a smi, it is *not* an object in the ECMA sense .
278- __ JumpIfSmi (r0, &use_receiver );
256+ // If the result is undefined, we jump out to using the implicit receiver .
257+ __ JumpIfNotRoot (r0, RootIndex:: kUndefinedValue , &check_receiver );
279258
280- // If the type of the result (stored in its map) is less than
281- // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
282- STATIC_ASSERT (LAST_JS_RECEIVER_TYPE == LAST_TYPE);
283- __ CompareObjectType (r0, r4, r5, FIRST_JS_RECEIVER_TYPE);
284- __ b (ge, &leave_frame);
285- __ b (&use_receiver);
259+ // Otherwise we do a smi check and fall through to check if the return value
260+ // is a valid receiver.
286261
287- __ bind (&do_throw);
288- __ CallRuntime (Runtime::kThrowConstructorReturnedNonObject );
262+ // Throw away the result of the constructor invocation and use the
263+ // on-stack receiver as the result.
264+ __ bind (&use_receiver);
265+ __ ldr (r0, MemOperand (sp, 0 * kPointerSize ));
266+ __ JumpIfRoot (r0, RootIndex::kTheHoleValue , &do_throw);
289267
290- // Throw away the result of the constructor invocation and use the
291- // on-stack receiver as the result .
292- __ bind (&use_receiver );
293- __ ldr (r0, MemOperand (sp, 0 * kPointerSize ));
294- __ JumpIfRoot (r0, RootIndex:: kTheHoleValue , &do_throw );
268+ __ bind (&leave_and_return);
269+ // Restore smi-tagged arguments count from the frame .
270+ __ ldr (r1, MemOperand (fp, ConstructFrameConstants:: kLengthOffset ) );
271+ // Leave construct frame.
272+ __ LeaveFrame (StackFrame::CONSTRUCT );
295273
296- __ bind (&leave_frame);
297- // Restore smi-tagged arguments count from the frame.
298- __ ldr (r1, MemOperand (fp, ConstructFrameConstants::kLengthOffset ));
299- // Leave construct frame.
300- }
301274 // Remove caller arguments from the stack and return.
302275 STATIC_ASSERT (kSmiTagSize == 1 && kSmiTag == 0 );
303276 __ add (sp, sp, Operand (r1, LSL, kPointerSizeLog2 - kSmiTagSize ));
304277 __ add (sp, sp, Operand (kPointerSize ));
305278 __ Jump (lr);
279+
280+ __ bind (&check_receiver);
281+ // If the result is a smi, it is *not* an object in the ECMA sense.
282+ __ JumpIfSmi (r0, &use_receiver);
283+
284+ // If the type of the result (stored in its map) is less than
285+ // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
286+ STATIC_ASSERT (LAST_JS_RECEIVER_TYPE == LAST_TYPE);
287+ __ CompareObjectType (r0, r4, r5, FIRST_JS_RECEIVER_TYPE);
288+ __ b (ge, &leave_and_return);
289+ __ b (&use_receiver);
290+
291+ __ bind (&do_throw);
292+ // Restore the context from the frame.
293+ __ ldr (cp, MemOperand (fp, ConstructFrameConstants::kContextOffset ));
294+ __ CallRuntime (Runtime::kThrowConstructorReturnedNonObject );
295+ __ bkpt (0 );
296+
297+ __ bind (&stack_overflow);
298+ // Restore the context from the frame.
299+ __ ldr (cp, MemOperand (fp, ConstructFrameConstants::kContextOffset ));
300+ __ CallRuntime (Runtime::kThrowStackOverflow );
301+ // Unreachable code.
302+ __ bkpt (0 );
306303}
307304
308305void Builtins::Generate_JSBuiltinsConstructStub (MacroAssembler* masm) {
0 commit comments