| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/debug.h" | 10 #include "src/debug.h" |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 __ B(hs, &ok); | 295 __ B(hs, &ok); |
| 296 | 296 |
| 297 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); | 297 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); |
| 298 GenerateTailCallToReturnedCode(masm); | 298 GenerateTailCallToReturnedCode(masm); |
| 299 | 299 |
| 300 __ Bind(&ok); | 300 __ Bind(&ok); |
| 301 GenerateTailCallToSharedCode(masm); | 301 GenerateTailCallToSharedCode(masm); |
| 302 } | 302 } |
| 303 | 303 |
| 304 | 304 |
| 305 static void Generate_Runtime_NewObject(MacroAssembler* masm, | |
| 306 bool create_memento, | |
| 307 Register original_constructor, | |
| 308 Label* count_incremented, | |
| 309 Label* allocated) { | |
| 310 if (create_memento) { | |
| 311 // Get the cell or allocation site. | |
| 312 __ Peek(x4, 3 * kXRegSize); | |
| 313 __ Push(x4); | |
| 314 __ Push(x1); // Argument for Runtime_NewObject. | |
| 315 __ Push(original_constructor); | |
| 316 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); | |
| 317 __ Mov(x4, x0); | |
| 318 // If we ended up using the runtime, and we want a memento, then the | |
| 319 // runtime call made it for us, and we shouldn't do create count | |
| 320 // increment. | |
| 321 __ jmp(count_incremented); | |
| 322 } else { | |
| 323 __ Push(x1); // Argument for Runtime_NewObject. | |
| 324 __ Push(original_constructor); | |
| 325 __ CallRuntime(Runtime::kNewObject, 2); | |
| 326 __ Mov(x4, x0); | |
| 327 __ jmp(allocated); | |
| 328 } | |
| 329 } | |
| 330 | |
| 331 | |
| 332 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 305 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| 333 bool is_api_function, | 306 bool is_api_function, |
| 334 bool create_memento) { | 307 bool create_memento) { |
| 335 // ----------- S t a t e ------------- | 308 // ----------- S t a t e ------------- |
| 336 // -- x0 : number of arguments | 309 // -- x0 : number of arguments |
| 337 // -- x1 : constructor function | 310 // -- x1 : constructor function |
| 338 // -- x2 : allocation site or undefined | 311 // -- x2 : allocation site or undefined |
| 339 // -- x3 : original constructor | 312 // -- x3 : original constructor |
| 340 // -- lr : return address | 313 // -- lr : return address |
| 341 // -- sp[...]: constructor arguments | 314 // -- sp[...]: constructor arguments |
| (...skipping 19 matching lines...) Expand all Loading... |
| 361 Register constructor = x1; | 334 Register constructor = x1; |
| 362 Register original_constructor = x3; | 335 Register original_constructor = x3; |
| 363 | 336 |
| 364 // Preserve the incoming parameters on the stack. | 337 // Preserve the incoming parameters on the stack. |
| 365 __ SmiTag(argc); | 338 __ SmiTag(argc); |
| 366 __ Push(argc, constructor, original_constructor); | 339 __ Push(argc, constructor, original_constructor); |
| 367 // sp[0]: new.target | 340 // sp[0]: new.target |
| 368 // sp[1]: Constructor function. | 341 // sp[1]: Constructor function. |
| 369 // sp[2]: number of arguments (smi-tagged) | 342 // sp[2]: number of arguments (smi-tagged) |
| 370 | 343 |
| 371 Label rt_call, count_incremented, allocated, normal_new; | |
| 372 __ Cmp(constructor, original_constructor); | |
| 373 __ B(eq, &normal_new); | |
| 374 Generate_Runtime_NewObject(masm, create_memento, original_constructor, | |
| 375 &count_incremented, &allocated); | |
| 376 | |
| 377 __ Bind(&normal_new); | |
| 378 | |
| 379 // Try to allocate the object without transitioning into C code. If any of | 344 // Try to allocate the object without transitioning into C code. If any of |
| 380 // the preconditions is not met, the code bails out to the runtime call. | 345 // the preconditions is not met, the code bails out to the runtime call. |
| 346 Label rt_call, allocated; |
| 381 if (FLAG_inline_new) { | 347 if (FLAG_inline_new) { |
| 382 ExternalReference debug_step_in_fp = | 348 ExternalReference debug_step_in_fp = |
| 383 ExternalReference::debug_step_in_fp_address(isolate); | 349 ExternalReference::debug_step_in_fp_address(isolate); |
| 384 __ Mov(x2, Operand(debug_step_in_fp)); | 350 __ Mov(x2, Operand(debug_step_in_fp)); |
| 385 __ Ldr(x2, MemOperand(x2)); | 351 __ Ldr(x2, MemOperand(x2)); |
| 386 __ Cbnz(x2, &rt_call); | 352 __ Cbnz(x2, &rt_call); |
| 353 |
| 354 // Fall back to runtime if the original constructor and function differ. |
| 355 __ Cmp(constructor, original_constructor); |
| 356 __ B(ne, &rt_call); |
| 357 |
| 387 // Load the initial map and verify that it is in fact a map. | 358 // Load the initial map and verify that it is in fact a map. |
| 388 Register init_map = x2; | 359 Register init_map = x2; |
| 389 __ Ldr(init_map, | 360 __ Ldr(init_map, |
| 390 FieldMemOperand(constructor, | 361 FieldMemOperand(constructor, |
| 391 JSFunction::kPrototypeOrInitialMapOffset)); | 362 JSFunction::kPrototypeOrInitialMapOffset)); |
| 392 __ JumpIfSmi(init_map, &rt_call); | 363 __ JumpIfSmi(init_map, &rt_call); |
| 393 __ JumpIfNotObjectType(init_map, x10, x11, MAP_TYPE, &rt_call); | 364 __ JumpIfNotObjectType(init_map, x10, x11, MAP_TYPE, &rt_call); |
| 394 | 365 |
| 395 // Check that the constructor is not constructing a JSFunction (see | 366 // Check that the constructor is not constructing a JSFunction (see |
| 396 // comments in Runtime_NewObject in runtime.cc). In which case the initial | 367 // comments in Runtime_NewObject in runtime.cc). In which case the initial |
| (...skipping 20 matching lines...) Expand all Loading... |
| 417 // Push the constructor and map to the stack, and the constructor again | 388 // Push the constructor and map to the stack, and the constructor again |
| 418 // as argument to the runtime call. | 389 // as argument to the runtime call. |
| 419 __ Push(constructor, init_map, constructor); | 390 __ Push(constructor, init_map, constructor); |
| 420 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); | 391 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); |
| 421 __ Pop(init_map, constructor); | 392 __ Pop(init_map, constructor); |
| 422 __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1)); | 393 __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1)); |
| 423 __ Bind(&allocate); | 394 __ Bind(&allocate); |
| 424 } | 395 } |
| 425 | 396 |
| 426 // Now allocate the JSObject on the heap. | 397 // Now allocate the JSObject on the heap. |
| 398 Label rt_call_reload_new_target; |
| 427 Register obj_size = x3; | 399 Register obj_size = x3; |
| 428 Register new_obj = x4; | 400 Register new_obj = x4; |
| 429 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); | 401 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); |
| 430 if (create_memento) { | 402 if (create_memento) { |
| 431 __ Add(x7, obj_size, | 403 __ Add(x7, obj_size, |
| 432 Operand(AllocationMemento::kSize / kPointerSize)); | 404 Operand(AllocationMemento::kSize / kPointerSize)); |
| 433 __ Allocate(x7, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); | 405 __ Allocate(x7, new_obj, x10, x11, &rt_call_reload_new_target, |
| 406 SIZE_IN_WORDS); |
| 434 } else { | 407 } else { |
| 435 __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); | 408 __ Allocate(obj_size, new_obj, x10, x11, &rt_call_reload_new_target, |
| 409 SIZE_IN_WORDS); |
| 436 } | 410 } |
| 437 | 411 |
| 438 // Allocated the JSObject, now initialize the fields. Map is set to | 412 // Allocated the JSObject, now initialize the fields. Map is set to |
| 439 // 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. |
| 440 // NB. the object pointer is not tagged, so MemOperand is used. | 414 // NB. the object pointer is not tagged, so MemOperand is used. |
| 441 Register empty = x5; | 415 Register empty = x5; |
| 442 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); | 416 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); |
| 443 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); | 417 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); |
| 444 STATIC_ASSERT(JSObject::kElementsOffset == | 418 STATIC_ASSERT(JSObject::kElementsOffset == |
| 445 (JSObject::kPropertiesOffset + kPointerSize)); | 419 (JSObject::kPropertiesOffset + kPointerSize)); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 first_prop = NoReg; | 493 first_prop = NoReg; |
| 520 prop_fields = NoReg; | 494 prop_fields = NoReg; |
| 521 } | 495 } |
| 522 | 496 |
| 523 // Add the object tag to make the JSObject real, so that we can continue | 497 // Add the object tag to make the JSObject real, so that we can continue |
| 524 // and jump into the continuation code at any time from now on. | 498 // and jump into the continuation code at any time from now on. |
| 525 __ Add(new_obj, new_obj, kHeapObjectTag); | 499 __ Add(new_obj, new_obj, kHeapObjectTag); |
| 526 | 500 |
| 527 // Continue with JSObject being successfully allocated. | 501 // Continue with JSObject being successfully allocated. |
| 528 __ B(&allocated); | 502 __ B(&allocated); |
| 503 |
| 504 // Reload the original constructor and fall-through. |
| 505 __ Bind(&rt_call_reload_new_target); |
| 506 __ Peek(x3, 0 * kXRegSize); |
| 529 } | 507 } |
| 530 | 508 |
| 531 // Allocate the new receiver object using the runtime call. | 509 // Allocate the new receiver object using the runtime call. |
| 510 // x1: constructor function |
| 511 // x3: original constructor |
| 532 __ Bind(&rt_call); | 512 __ Bind(&rt_call); |
| 533 Generate_Runtime_NewObject(masm, create_memento, constructor, | 513 Label count_incremented; |
| 534 &count_incremented, &allocated); | 514 if (create_memento) { |
| 515 // Get the cell or allocation site. |
| 516 __ Peek(x4, 3 * kXRegSize); |
| 517 __ Push(x4, constructor, original_constructor); // arguments 1-3 |
| 518 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); |
| 519 __ Mov(x4, x0); |
| 520 // If we ended up using the runtime, and we want a memento, then the |
| 521 // runtime call made it for us, and we shouldn't do create count |
| 522 // increment. |
| 523 __ B(&count_incremented); |
| 524 } else { |
| 525 __ Push(constructor, original_constructor); // arguments 1-2 |
| 526 __ CallRuntime(Runtime::kNewObject, 2); |
| 527 __ Mov(x4, x0); |
| 528 } |
| 535 | 529 |
| 536 // Receiver for constructor call allocated. | 530 // Receiver for constructor call allocated. |
| 537 // x4: JSObject | 531 // x4: JSObject |
| 538 __ Bind(&allocated); | 532 __ Bind(&allocated); |
| 539 | 533 |
| 540 if (create_memento) { | 534 if (create_memento) { |
| 541 __ Peek(x10, 3 * kXRegSize); | 535 __ Peek(x10, 3 * kXRegSize); |
| 542 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); | 536 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); |
| 543 // r2 is an AllocationSite. We are creating a memento from it, so we | 537 // r2 is an AllocationSite. We are creating a memento from it, so we |
| 544 // need to increment the memento create count. | 538 // need to increment the memento create count. |
| (...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1795 } | 1789 } |
| 1796 } | 1790 } |
| 1797 | 1791 |
| 1798 | 1792 |
| 1799 #undef __ | 1793 #undef __ |
| 1800 | 1794 |
| 1801 } // namespace internal | 1795 } // namespace internal |
| 1802 } // namespace v8 | 1796 } // namespace v8 |
| 1803 | 1797 |
| 1804 #endif // V8_TARGET_ARCH_ARM | 1798 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |