Skip to content

Commit cd5f483

Browse files
isheludkoCommit bot
authored andcommitted
[es6] Better support for built-ins subclassing.
Create proper initial map for original constructor (new.target) instead of doing prototype transition on the base constructor's initial map. This approach fixes in-object slack tracking for subclass instances. This CL also fixes subclassing from String. BUG=v8:3101, v8:3330 LOG=Y Review URL: https://codereview.chromium.org/1427483002 Cr-Commit-Position: refs/heads/master@{#31680}
1 parent 8a2618a commit cd5f483

14 files changed

Lines changed: 784 additions & 124 deletions

src/arm/builtins-arm.cc

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -213,53 +213,61 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
213213
// ----------- S t a t e -------------
214214
// -- r0 : number of arguments
215215
// -- r1 : constructor function
216+
// -- r3 : original constructor
216217
// -- lr : return address
217218
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
218219
// -- sp[argc * 4] : receiver
219220
// -----------------------------------
220221

221-
// 1. Load the first argument into r0 and get rid of the rest (including the
222+
// 1. Load the first argument into r2 and get rid of the rest (including the
222223
// receiver).
223224
{
224225
Label no_arguments, done;
225226
__ sub(r0, r0, Operand(1), SetCC);
226227
__ b(lo, &no_arguments);
227-
__ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex));
228+
__ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex));
228229
__ Drop(2);
229230
__ b(&done);
230231
__ bind(&no_arguments);
231-
__ LoadRoot(r0, Heap::kempty_stringRootIndex);
232+
__ LoadRoot(r2, Heap::kempty_stringRootIndex);
232233
__ Drop(1);
233234
__ bind(&done);
234235
}
235236

236-
// 2. Make sure r0 is a string.
237+
// 2. Make sure r2 is a string.
237238
{
238239
Label convert, done_convert;
239-
__ JumpIfSmi(r0, &convert);
240-
__ CompareObjectType(r0, r2, r2, FIRST_NONSTRING_TYPE);
240+
__ JumpIfSmi(r2, &convert);
241+
__ CompareObjectType(r2, r4, r4, FIRST_NONSTRING_TYPE);
241242
__ b(lo, &done_convert);
242243
__ bind(&convert);
243244
{
244245
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
245246
ToStringStub stub(masm->isolate());
246-
__ Push(r1);
247+
__ Push(r1, r3);
248+
__ Move(r0, r2);
247249
__ CallStub(&stub);
248-
__ Pop(r1);
250+
__ Move(r2, r0);
251+
__ Pop(r1, r3);
249252
}
250253
__ bind(&done_convert);
251254
}
252255

253256
// 3. Allocate a JSValue wrapper for the string.
254257
{
255258
// ----------- S t a t e -------------
256-
// -- r0 : the first argument
259+
// -- r2 : the first argument
257260
// -- r1 : constructor function
261+
// -- r3 : original constructor
258262
// -- lr : return address
259263
// -----------------------------------
260264

261-
Label allocate, done_allocate;
262-
__ Move(r2, r0);
265+
Label allocate, done_allocate, rt_call;
266+
267+
// Fall back to runtime if the original constructor and function differ.
268+
__ cmp(r1, r3);
269+
__ b(ne, &rt_call);
270+
263271
__ Allocate(JSValue::kSize, r0, r3, r4, &allocate, TAG_OBJECT);
264272
__ bind(&done_allocate);
265273

@@ -283,6 +291,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
283291
__ Pop(r1, r2);
284292
}
285293
__ b(&done_allocate);
294+
295+
// Fallback to the runtime to create new object.
296+
__ bind(&rt_call);
297+
{
298+
FrameScope scope(masm, StackFrame::INTERNAL);
299+
__ Push(r1, r2);
300+
__ Push(r1, r3); // constructor function, original constructor
301+
__ CallRuntime(Runtime::kNewObject, 2);
302+
__ Pop(r1, r2);
303+
}
304+
__ str(r2, FieldMemOperand(r0, JSValue::kValueOffset));
305+
__ Ret();
286306
}
287307
}
288308

@@ -500,8 +520,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
500520
// r3: original constructor
501521
__ bind(&rt_call);
502522

503-
__ push(r1); // argument 2/1: constructor function
504-
__ push(r3); // argument 3/2: original constructor
523+
__ push(r1); // constructor function
524+
__ push(r3); // original constructor
505525
__ CallRuntime(Runtime::kNewObject, 2);
506526
__ mov(r4, r0);
507527

src/arm64/builtins-arm64.cc

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
209209
// ----------- S t a t e -------------
210210
// -- x0 : number of arguments
211211
// -- x1 : constructor function
212+
// -- x3 : original constructor
212213
// -- lr : return address
213214
// -- sp[(argc - n - 1) * 8] : arg[n] (zero based)
214215
// -- sp[argc * 8] : receiver
@@ -234,29 +235,35 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
234235
{
235236
Label convert, done_convert;
236237
__ JumpIfSmi(x2, &convert);
237-
__ JumpIfObjectType(x2, x3, x3, FIRST_NONSTRING_TYPE, &done_convert, lo);
238+
__ JumpIfObjectType(x2, x4, x4, FIRST_NONSTRING_TYPE, &done_convert, lo);
238239
__ Bind(&convert);
239240
{
240241
FrameScope scope(masm, StackFrame::INTERNAL);
241242
ToStringStub stub(masm->isolate());
242-
__ Push(x1);
243+
__ Push(x1, x3);
243244
__ Move(x0, x2);
244245
__ CallStub(&stub);
245246
__ Move(x2, x0);
246-
__ Pop(x1);
247+
__ Pop(x1, x3);
247248
}
248249
__ Bind(&done_convert);
249250
}
250251

251252
// 3. Allocate a JSValue wrapper for the string.
252253
{
253254
// ----------- S t a t e -------------
254-
// -- x1 : constructor function
255255
// -- x2 : the first argument
256+
// -- x1 : constructor function
257+
// -- x3 : original constructor
256258
// -- lr : return address
257259
// -----------------------------------
258260

259-
Label allocate, done_allocate;
261+
Label allocate, done_allocate, rt_call;
262+
263+
// Fall back to runtime if the original constructor and function differ.
264+
__ cmp(x1, x3);
265+
__ B(ne, &rt_call);
266+
260267
__ Allocate(JSValue::kSize, x0, x3, x4, &allocate, TAG_OBJECT);
261268
__ Bind(&done_allocate);
262269

@@ -280,6 +287,17 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
280287
__ Pop(x2, x1);
281288
}
282289
__ B(&done_allocate);
290+
291+
// Fallback to the runtime to create new object.
292+
__ bind(&rt_call);
293+
{
294+
FrameScope scope(masm, StackFrame::INTERNAL);
295+
__ Push(x1, x2, x1, x3); // constructor function, original constructor
296+
__ CallRuntime(Runtime::kNewObject, 2);
297+
__ Pop(x2, x1);
298+
}
299+
__ Str(x2, FieldMemOperand(x0, JSValue::kValueOffset));
300+
__ Ret();
283301
}
284302
}
285303

@@ -336,7 +354,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
336354
// -- x0 : number of arguments
337355
// -- x1 : constructor function
338356
// -- x2 : allocation site or undefined
339-
// -- x3 : original constructor
357+
// -- x3 : original constructor
340358
// -- lr : return address
341359
// -- sp[...]: constructor arguments
342360
// -----------------------------------

src/heap/heap.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3438,7 +3438,7 @@ void Heap::InitializeJSObjectFromMap(JSObject* obj, FixedArray* properties,
34383438
if (constructor->IsJSFunction() &&
34393439
JSFunction::cast(constructor)->IsInobjectSlackTrackingInProgress()) {
34403440
// We might want to shrink the object later.
3441-
DCHECK(obj->GetInternalFieldCount() == 0);
3441+
DCHECK_EQ(0, obj->GetInternalFieldCount());
34423442
filler = Heap::one_pointer_filler_map();
34433443
} else {
34443444
filler = Heap::undefined_value();

src/ia32/builtins-ia32.cc

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,8 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
280280
// runtime.
281281
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
282282
__ mov(edi, Operand(esp, offset));
283-
__ push(edi); // argument 2/1: constructor function
284-
__ push(edx); // argument 3/2: original constructor
283+
__ push(edi); // constructor function
284+
__ push(edx); // original constructor
285285
__ CallRuntime(Runtime::kNewObject, 2);
286286
__ mov(ebx, eax); // store result in ebx
287287

@@ -1363,6 +1363,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
13631363
// ----------- S t a t e -------------
13641364
// -- eax : number of arguments
13651365
// -- edi : constructor function
1366+
// -- edx : original constructor
13661367
// -- esp[0] : return address
13671368
// -- esp[(argc - n) * 4] : arg[n] (zero-based)
13681369
// -- esp[(argc + 1) * 4] : receiver
@@ -1388,16 +1389,18 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
13881389
{
13891390
Label convert, done_convert;
13901391
__ JumpIfSmi(ebx, &convert, Label::kNear);
1391-
__ CmpObjectType(ebx, FIRST_NONSTRING_TYPE, edx);
1392+
__ CmpObjectType(ebx, FIRST_NONSTRING_TYPE, ecx);
13921393
__ j(below, &done_convert);
13931394
__ bind(&convert);
13941395
{
13951396
FrameScope scope(masm, StackFrame::INTERNAL);
13961397
ToStringStub stub(masm->isolate());
13971398
__ Push(edi);
1399+
__ Push(edx);
13981400
__ Move(eax, ebx);
13991401
__ CallStub(&stub);
14001402
__ Move(ebx, eax);
1403+
__ Pop(edx);
14011404
__ Pop(edi);
14021405
}
14031406
__ bind(&done_convert);
@@ -1408,9 +1411,15 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
14081411
// ----------- S t a t e -------------
14091412
// -- ebx : the first argument
14101413
// -- edi : constructor function
1414+
// -- edx : original constructor
14111415
// -----------------------------------
14121416

1413-
Label allocate, done_allocate;
1417+
Label allocate, done_allocate, rt_call;
1418+
1419+
// Fall back to runtime if the original constructor and constructor differ.
1420+
__ cmp(edx, edi);
1421+
__ j(not_equal, &rt_call);
1422+
14141423
__ Allocate(JSValue::kSize, eax, ecx, no_reg, &allocate, TAG_OBJECT);
14151424
__ bind(&done_allocate);
14161425

@@ -1437,6 +1446,21 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
14371446
__ Pop(ebx);
14381447
}
14391448
__ jmp(&done_allocate);
1449+
1450+
// Fallback to the runtime to create new object.
1451+
__ bind(&rt_call);
1452+
{
1453+
FrameScope scope(masm, StackFrame::INTERNAL);
1454+
__ Push(ebx);
1455+
__ Push(edi);
1456+
__ Push(edi); // constructor function
1457+
__ Push(edx); // original constructor
1458+
__ CallRuntime(Runtime::kNewObject, 2);
1459+
__ Pop(edi);
1460+
__ Pop(ebx);
1461+
}
1462+
__ mov(FieldOperand(eax, JSValue::kValueOffset), ebx);
1463+
__ Ret();
14401464
}
14411465
}
14421466

src/mips/builtins-mips.cc

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
227227
// ----------- S t a t e -------------
228228
// -- a0 : number of arguments
229229
// -- a1 : constructor function
230+
// -- a3 : original constructor
230231
// -- ra : return address
231232
// -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
232233
// -- sp[argc * 4] : receiver
@@ -260,10 +261,10 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
260261
{
261262
FrameScope scope(masm, StackFrame::INTERNAL);
262263
ToStringStub stub(masm->isolate());
263-
__ Push(a1);
264+
__ Push(a1, a3);
264265
__ CallStub(&stub);
265266
__ Move(a0, v0);
266-
__ Pop(a1);
267+
__ Pop(a1, a3);
267268
}
268269
__ bind(&done_convert);
269270
}
@@ -273,10 +274,15 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
273274
// ----------- S t a t e -------------
274275
// -- a0 : the first argument
275276
// -- a1 : constructor function
277+
// -- a3 : original constructor
276278
// -- ra : return address
277279
// -----------------------------------
278280

279-
Label allocate, done_allocate;
281+
Label allocate, done_allocate, rt_call;
282+
283+
// Fall back to runtime if the original constructor and function differ.
284+
__ Branch(&rt_call, ne, a1, Operand(a3));
285+
280286
__ Allocate(JSValue::kSize, v0, a2, a3, &allocate, TAG_OBJECT);
281287
__ bind(&done_allocate);
282288

@@ -300,6 +306,17 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
300306
__ Pop(a0, a1);
301307
}
302308
__ jmp(&done_allocate);
309+
310+
// Fallback to the runtime to create new object.
311+
__ bind(&rt_call);
312+
{
313+
FrameScope scope(masm, StackFrame::INTERNAL);
314+
__ Push(a0, a1, a1, a3); // constructor function, original constructor
315+
__ CallRuntime(Runtime::kNewObject, 2);
316+
__ Pop(a0, a1);
317+
}
318+
__ Ret(USE_DELAY_SLOT);
319+
__ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset));
303320
}
304321
}
305322

@@ -510,7 +527,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
510527
// a3: original constructor
511528
__ bind(&rt_call);
512529

513-
__ Push(a1, a3); // arguments 2-3 / 1-2
530+
__ Push(a1, a3); // constructor function, original constructor
514531
__ CallRuntime(Runtime::kNewObject, 2);
515532
__ mov(t4, v0);
516533

src/mips64/builtins-mips64.cc

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
224224
// ----------- S t a t e -------------
225225
// -- a0 : number of arguments
226226
// -- a1 : constructor function
227+
// -- a3 : original constructor
227228
// -- ra : return address
228229
// -- sp[(argc - n - 1) * 8] : arg[n] (zero based)
229230
// -- sp[argc * 8] : receiver
@@ -257,10 +258,10 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
257258
{
258259
FrameScope scope(masm, StackFrame::INTERNAL);
259260
ToStringStub stub(masm->isolate());
260-
__ Push(a1);
261+
__ Push(a1, a3);
261262
__ CallStub(&stub);
262263
__ Move(a0, v0);
263-
__ Pop(a1);
264+
__ Pop(a1, a3);
264265
}
265266
__ bind(&done_convert);
266267
}
@@ -270,10 +271,15 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
270271
// ----------- S t a t e -------------
271272
// -- a0 : the first argument
272273
// -- a1 : constructor function
274+
// -- a3 : original constructor
273275
// -- ra : return address
274276
// -----------------------------------
275277

276-
Label allocate, done_allocate;
278+
Label allocate, done_allocate, rt_call;
279+
280+
// Fall back to runtime if the original constructor and function differ.
281+
__ Branch(&rt_call, ne, a1, Operand(a3));
282+
277283
__ Allocate(JSValue::kSize, v0, a2, a3, &allocate, TAG_OBJECT);
278284
__ bind(&done_allocate);
279285

@@ -297,6 +303,17 @@ void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
297303
__ Pop(a0, a1);
298304
}
299305
__ jmp(&done_allocate);
306+
307+
// Fallback to the runtime to create new object.
308+
__ bind(&rt_call);
309+
{
310+
FrameScope scope(masm, StackFrame::INTERNAL);
311+
__ Push(a0, a1, a1, a3); // constructor function, original constructor
312+
__ CallRuntime(Runtime::kNewObject, 2);
313+
__ Pop(a0, a1);
314+
}
315+
__ sd(a0, FieldMemOperand(v0, JSValue::kValueOffset));
316+
__ Ret();
300317
}
301318
}
302319

@@ -508,7 +525,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
508525
// a3: original constructor
509526
__ bind(&rt_call);
510527

511-
__ Push(a1, a3); // arguments 2-3 / 1-2
528+
__ Push(a1, a3); // constructor function, original constructor
512529
__ CallRuntime(Runtime::kNewObject, 2);
513530
__ mov(t0, v0);
514531

0 commit comments

Comments
 (0)