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

Side by Side Diff: src/arm/builtins-arm.cc

Issue 1227163011: Cleanup Generate_JSConstructStubHelper a bit. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Comment typo. Created 5 years, 5 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 unified diff | Download patch
« no previous file with comments | « no previous file | src/arm64/builtins-arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_ARM 7 #if V8_TARGET_ARCH_ARM
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/debug.h" 10 #include "src/debug.h"
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 __ b(hs, &ok); 304 __ b(hs, &ok);
305 305
306 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); 306 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
307 GenerateTailCallToReturnedCode(masm); 307 GenerateTailCallToReturnedCode(masm);
308 308
309 __ bind(&ok); 309 __ bind(&ok);
310 GenerateTailCallToSharedCode(masm); 310 GenerateTailCallToSharedCode(masm);
311 } 311 }
312 312
313 313
314 static void Generate_Runtime_NewObject(MacroAssembler* masm,
315 bool create_memento,
316 Register original_constructor,
317 Label* count_incremented,
318 Label* allocated) {
319 if (create_memento) {
320 // Get the cell or allocation site.
321 __ ldr(r2, MemOperand(sp, 3 * kPointerSize));
322 __ push(r2);
323 }
324
325 __ push(r1); // argument for Runtime_NewObject
326 __ push(original_constructor); // original constructor
327 if (create_memento) {
328 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3);
329 } else {
330 __ CallRuntime(Runtime::kNewObject, 2);
331 }
332 __ mov(r4, r0);
333
334 // Runtime_NewObjectWithAllocationSite increments allocation count.
335 // Skip the increment.
336 if (create_memento) {
337 __ jmp(count_incremented);
338 } else {
339 __ jmp(allocated);
340 }
341 }
342
343
344 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 314 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
345 bool is_api_function, 315 bool is_api_function,
346 bool create_memento) { 316 bool create_memento) {
347 // ----------- S t a t e ------------- 317 // ----------- S t a t e -------------
348 // -- r0 : number of arguments 318 // -- r0 : number of arguments
349 // -- r1 : constructor function 319 // -- r1 : constructor function
350 // -- r2 : allocation site or undefined 320 // -- r2 : allocation site or undefined
351 // -- r3 : original constructor 321 // -- r3 : original constructor
352 // -- lr : return address 322 // -- lr : return address
353 // -- sp[...]: constructor arguments 323 // -- sp[...]: constructor arguments
(...skipping 12 matching lines...) Expand all
366 __ AssertUndefinedOrAllocationSite(r2, r4); 336 __ AssertUndefinedOrAllocationSite(r2, r4);
367 __ push(r2); 337 __ push(r2);
368 } 338 }
369 339
370 // Preserve the incoming parameters on the stack. 340 // Preserve the incoming parameters on the stack.
371 __ SmiTag(r0); 341 __ SmiTag(r0);
372 __ push(r0); 342 __ push(r0);
373 __ push(r1); 343 __ push(r1);
374 __ push(r3); 344 __ push(r3);
375 345
376 Label rt_call, allocated, normal_new, count_incremented;
377 __ cmp(r1, r3);
378 __ b(eq, &normal_new);
379
380 // Original constructor and function are different.
381 Generate_Runtime_NewObject(masm, create_memento, r3, &count_incremented,
382 &allocated);
383 __ bind(&normal_new);
384
385 // Try to allocate the object without transitioning into C code. If any of 346 // Try to allocate the object without transitioning into C code. If any of
386 // the preconditions is not met, the code bails out to the runtime call. 347 // the preconditions is not met, the code bails out to the runtime call.
348 Label rt_call, allocated;
387 if (FLAG_inline_new) { 349 if (FLAG_inline_new) {
388 ExternalReference debug_step_in_fp = 350 ExternalReference debug_step_in_fp =
389 ExternalReference::debug_step_in_fp_address(isolate); 351 ExternalReference::debug_step_in_fp_address(isolate);
390 __ mov(r2, Operand(debug_step_in_fp)); 352 __ mov(r2, Operand(debug_step_in_fp));
391 __ ldr(r2, MemOperand(r2)); 353 __ ldr(r2, MemOperand(r2));
392 __ tst(r2, r2); 354 __ tst(r2, r2);
393 __ b(ne, &rt_call); 355 __ b(ne, &rt_call);
394 356
357 // Fall back to runtime if the original constructor and function differ.
358 __ cmp(r1, r3);
359 __ b(ne, &rt_call);
360
395 // Load the initial map and verify that it is in fact a map. 361 // Load the initial map and verify that it is in fact a map.
396 // r1: constructor function 362 // r1: constructor function
397 __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); 363 __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
398 __ JumpIfSmi(r2, &rt_call); 364 __ JumpIfSmi(r2, &rt_call);
399 __ CompareObjectType(r2, r3, r4, MAP_TYPE); 365 __ CompareObjectType(r2, r5, r4, MAP_TYPE);
400 __ b(ne, &rt_call); 366 __ b(ne, &rt_call);
401 367
402 // Check that the constructor is not constructing a JSFunction (see 368 // Check that the constructor is not constructing a JSFunction (see
403 // comments in Runtime_NewObject in runtime.cc). In which case the 369 // comments in Runtime_NewObject in runtime.cc). In which case the
404 // initial map's instance type would be JS_FUNCTION_TYPE. 370 // initial map's instance type would be JS_FUNCTION_TYPE.
405 // r1: constructor function 371 // r1: constructor function
406 // r2: initial map 372 // r2: initial map
407 __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE); 373 __ CompareInstanceType(r2, r5, JS_FUNCTION_TYPE);
408 __ b(eq, &rt_call); 374 __ b(eq, &rt_call);
409 375
410 if (!is_api_function) { 376 if (!is_api_function) {
411 Label allocate; 377 Label allocate;
412 MemOperand bit_field3 = FieldMemOperand(r2, Map::kBitField3Offset); 378 MemOperand bit_field3 = FieldMemOperand(r2, Map::kBitField3Offset);
413 // Check if slack tracking is enabled. 379 // Check if slack tracking is enabled.
414 __ ldr(r4, bit_field3); 380 __ ldr(r4, bit_field3);
415 __ DecodeField<Map::Counter>(r3, r4); 381 __ DecodeField<Map::Counter>(r3, r4);
416 __ cmp(r3, Operand(Map::kSlackTrackingCounterEnd)); 382 __ cmp(r3, Operand(Map::kSlackTrackingCounterEnd));
417 __ b(lt, &allocate); 383 __ b(lt, &allocate);
(...skipping 10 matching lines...) Expand all
428 394
429 __ pop(r2); 395 __ pop(r2);
430 __ pop(r1); 396 __ pop(r1);
431 397
432 __ bind(&allocate); 398 __ bind(&allocate);
433 } 399 }
434 400
435 // Now allocate the JSObject on the heap. 401 // Now allocate the JSObject on the heap.
436 // r1: constructor function 402 // r1: constructor function
437 // r2: initial map 403 // r2: initial map
404 Label rt_call_reload_new_target;
438 __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset)); 405 __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset));
439 if (create_memento) { 406 if (create_memento) {
440 __ add(r3, r3, Operand(AllocationMemento::kSize / kPointerSize)); 407 __ add(r3, r3, Operand(AllocationMemento::kSize / kPointerSize));
441 } 408 }
442 409
443 __ Allocate(r3, r4, r5, r6, &rt_call, SIZE_IN_WORDS); 410 __ Allocate(r3, r4, r5, r6, &rt_call_reload_new_target, SIZE_IN_WORDS);
444 411
445 // Allocated the JSObject, now initialize the fields. Map is set to 412 // Allocated the JSObject, now initialize the fields. Map is set to
446 // initial map and properties and elements are set to empty fixed array. 413 // initial map and properties and elements are set to empty fixed array.
447 // r1: constructor function 414 // r1: constructor function
448 // r2: initial map 415 // r2: initial map
449 // r3: object size (including memento if create_memento) 416 // r3: object size (including memento if create_memento)
450 // r4: JSObject (not tagged) 417 // r4: JSObject (not tagged)
451 __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex); 418 __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex);
452 __ mov(r5, r4); 419 __ mov(r5, r4);
453 DCHECK_EQ(0 * kPointerSize, JSObject::kMapOffset); 420 DCHECK_EQ(0 * kPointerSize, JSObject::kMapOffset);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 __ InitializeFieldsWithFiller(r5, r0, r6); 484 __ InitializeFieldsWithFiller(r5, r0, r6);
518 } 485 }
519 486
520 // Add the object tag to make the JSObject real, so that we can continue 487 // Add the object tag to make the JSObject real, so that we can continue
521 // and jump into the continuation code at any time from now on. 488 // and jump into the continuation code at any time from now on.
522 __ add(r4, r4, Operand(kHeapObjectTag)); 489 __ add(r4, r4, Operand(kHeapObjectTag));
523 490
524 // Continue with JSObject being successfully allocated 491 // Continue with JSObject being successfully allocated
525 // r4: JSObject 492 // r4: JSObject
526 __ jmp(&allocated); 493 __ jmp(&allocated);
494
495 // Reload the original constructor and fall-through.
496 __ bind(&rt_call_reload_new_target);
497 __ ldr(r3, MemOperand(sp, 0 * kPointerSize));
527 } 498 }
528 499
529 // Allocate the new receiver object using the runtime call. 500 // Allocate the new receiver object using the runtime call.
530 // r1: constructor function 501 // r1: constructor function
502 // r3: original constructor
531 __ bind(&rt_call); 503 __ bind(&rt_call);
532 Generate_Runtime_NewObject(masm, create_memento, r1, &count_incremented, 504 if (create_memento) {
533 &allocated); 505 // Get the cell or allocation site.
506 __ ldr(r2, MemOperand(sp, 3 * kPointerSize));
507 __ push(r2); // argument 1: allocation site
508 }
509
510 __ push(r1); // argument 2/1: constructor function
511 __ push(r3); // argument 3/2: original constructor
512 if (create_memento) {
513 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3);
514 } else {
515 __ CallRuntime(Runtime::kNewObject, 2);
516 }
517 __ mov(r4, r0);
518
519 // Runtime_NewObjectWithAllocationSite increments allocation count.
520 // Skip the increment.
521 Label count_incremented;
522 if (create_memento) {
523 __ jmp(&count_incremented);
524 }
534 525
535 // Receiver for constructor call allocated. 526 // Receiver for constructor call allocated.
536 // r4: JSObject 527 // r4: JSObject
537 __ bind(&allocated); 528 __ bind(&allocated);
538 529
539 if (create_memento) { 530 if (create_memento) {
540 __ ldr(r2, MemOperand(sp, 3 * kPointerSize)); 531 __ ldr(r2, MemOperand(sp, 3 * kPointerSize));
541 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); 532 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
542 __ cmp(r2, r5); 533 __ cmp(r2, r5);
543 __ b(eq, &count_incremented); 534 __ b(eq, &count_incremented);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 // sp[2]: number of arguments (smi-tagged) 603 // sp[2]: number of arguments (smi-tagged)
613 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 604 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
614 605
615 // If the result is an object (in the ECMA sense), we should get rid 606 // If the result is an object (in the ECMA sense), we should get rid
616 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 607 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
617 // on page 74. 608 // on page 74.
618 Label use_receiver, exit; 609 Label use_receiver, exit;
619 610
620 // If the result is a smi, it is *not* an object in the ECMA sense. 611 // If the result is a smi, it is *not* an object in the ECMA sense.
621 // r0: result 612 // r0: result
622 // sp[0]: receiver (newly allocated object) 613 // sp[0]: receiver
623 // sp[1]: new.target (if used) 614 // sp[1]: new.target
624 // sp[1/2]: number of arguments (smi-tagged) 615 // sp[2]: number of arguments (smi-tagged)
625 __ JumpIfSmi(r0, &use_receiver); 616 __ JumpIfSmi(r0, &use_receiver);
626 617
627 // If the type of the result (stored in its map) is less than 618 // If the type of the result (stored in its map) is less than
628 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. 619 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
629 __ CompareObjectType(r0, r1, r3, FIRST_SPEC_OBJECT_TYPE); 620 __ CompareObjectType(r0, r1, r3, FIRST_SPEC_OBJECT_TYPE);
630 __ b(ge, &exit); 621 __ b(ge, &exit);
631 622
632 // Throw away the result of the constructor invocation and use the 623 // Throw away the result of the constructor invocation and use the
633 // on-stack receiver as the result. 624 // on-stack receiver as the result.
634 __ bind(&use_receiver); 625 __ bind(&use_receiver);
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 } 1730 }
1740 } 1731 }
1741 1732
1742 1733
1743 #undef __ 1734 #undef __
1744 1735
1745 } // namespace internal 1736 } // namespace internal
1746 } // namespace v8 1737 } // namespace v8
1747 1738
1748 #endif // V8_TARGET_ARCH_ARM 1739 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/builtins-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698