| OLD | NEW |
| 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 #if V8_TARGET_ARCH_ARM | 5 #if V8_TARGET_ARCH_ARM |
| 6 | 6 |
| 7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
| 8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 3347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3358 Label fast_elements_case; | 3358 Label fast_elements_case; |
| 3359 __ cmp(r3, Operand(FAST_ELEMENTS)); | 3359 __ cmp(r3, Operand(FAST_ELEMENTS)); |
| 3360 __ b(eq, &fast_elements_case); | 3360 __ b(eq, &fast_elements_case); |
| 3361 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 3361 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
| 3362 | 3362 |
| 3363 __ bind(&fast_elements_case); | 3363 __ bind(&fast_elements_case); |
| 3364 GenerateCase(masm, FAST_ELEMENTS); | 3364 GenerateCase(masm, FAST_ELEMENTS); |
| 3365 } | 3365 } |
| 3366 | 3366 |
| 3367 | 3367 |
| 3368 void FastNewObjectStub::Generate(MacroAssembler* masm) { | |
| 3369 // ----------- S t a t e ------------- | |
| 3370 // -- r1 : target | |
| 3371 // -- r3 : new target | |
| 3372 // -- cp : context | |
| 3373 // -- lr : return address | |
| 3374 // ----------------------------------- | |
| 3375 __ AssertFunction(r1); | |
| 3376 __ AssertReceiver(r3); | |
| 3377 | |
| 3378 // Verify that the new target is a JSFunction. | |
| 3379 Label new_object; | |
| 3380 __ CompareObjectType(r3, r2, r2, JS_FUNCTION_TYPE); | |
| 3381 __ b(ne, &new_object); | |
| 3382 | |
| 3383 // Load the initial map and verify that it's in fact a map. | |
| 3384 __ ldr(r2, FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset)); | |
| 3385 __ JumpIfSmi(r2, &new_object); | |
| 3386 __ CompareObjectType(r2, r0, r0, MAP_TYPE); | |
| 3387 __ b(ne, &new_object); | |
| 3388 | |
| 3389 // Fall back to runtime if the target differs from the new target's | |
| 3390 // initial map constructor. | |
| 3391 __ ldr(r0, FieldMemOperand(r2, Map::kConstructorOrBackPointerOffset)); | |
| 3392 __ cmp(r0, r1); | |
| 3393 __ b(ne, &new_object); | |
| 3394 | |
| 3395 // Allocate the JSObject on the heap. | |
| 3396 Label allocate, done_allocate; | |
| 3397 __ ldrb(r4, FieldMemOperand(r2, Map::kInstanceSizeOffset)); | |
| 3398 __ Allocate(r4, r0, r5, r6, &allocate, SIZE_IN_WORDS); | |
| 3399 __ bind(&done_allocate); | |
| 3400 | |
| 3401 // Initialize the JSObject fields. | |
| 3402 __ str(r2, FieldMemOperand(r0, JSObject::kMapOffset)); | |
| 3403 __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex); | |
| 3404 __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset)); | |
| 3405 __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset)); | |
| 3406 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); | |
| 3407 __ add(r1, r0, Operand(JSObject::kHeaderSize - kHeapObjectTag)); | |
| 3408 | |
| 3409 // ----------- S t a t e ------------- | |
| 3410 // -- r0 : result (tagged) | |
| 3411 // -- r1 : result fields (untagged) | |
| 3412 // -- r5 : result end (untagged) | |
| 3413 // -- r2 : initial map | |
| 3414 // -- cp : context | |
| 3415 // -- lr : return address | |
| 3416 // ----------------------------------- | |
| 3417 | |
| 3418 // Perform in-object slack tracking if requested. | |
| 3419 Label slack_tracking; | |
| 3420 STATIC_ASSERT(Map::kNoSlackTracking == 0); | |
| 3421 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex); | |
| 3422 __ ldr(r3, FieldMemOperand(r2, Map::kBitField3Offset)); | |
| 3423 __ tst(r3, Operand(Map::ConstructionCounter::kMask)); | |
| 3424 __ b(ne, &slack_tracking); | |
| 3425 { | |
| 3426 // Initialize all in-object fields with undefined. | |
| 3427 __ InitializeFieldsWithFiller(r1, r5, r6); | |
| 3428 __ Ret(); | |
| 3429 } | |
| 3430 __ bind(&slack_tracking); | |
| 3431 { | |
| 3432 // Decrease generous allocation count. | |
| 3433 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); | |
| 3434 __ sub(r3, r3, Operand(1 << Map::ConstructionCounter::kShift)); | |
| 3435 __ str(r3, FieldMemOperand(r2, Map::kBitField3Offset)); | |
| 3436 | |
| 3437 // Initialize the in-object fields with undefined. | |
| 3438 __ ldrb(r4, FieldMemOperand(r2, Map::kUnusedPropertyFieldsOffset)); | |
| 3439 __ sub(r4, r5, Operand(r4, LSL, kPointerSizeLog2)); | |
| 3440 __ InitializeFieldsWithFiller(r1, r4, r6); | |
| 3441 | |
| 3442 // Initialize the remaining (reserved) fields with one pointer filler map. | |
| 3443 __ LoadRoot(r6, Heap::kOnePointerFillerMapRootIndex); | |
| 3444 __ InitializeFieldsWithFiller(r1, r5, r6); | |
| 3445 | |
| 3446 // Check if we can finalize the instance size. | |
| 3447 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); | |
| 3448 __ tst(r3, Operand(Map::ConstructionCounter::kMask)); | |
| 3449 __ Ret(ne); | |
| 3450 | |
| 3451 // Finalize the instance size. | |
| 3452 { | |
| 3453 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
| 3454 __ Push(r0, r2); | |
| 3455 __ CallRuntime(Runtime::kFinalizeInstanceSize); | |
| 3456 __ Pop(r0); | |
| 3457 } | |
| 3458 __ Ret(); | |
| 3459 } | |
| 3460 | |
| 3461 // Fall back to %AllocateInNewSpace. | |
| 3462 __ bind(&allocate); | |
| 3463 { | |
| 3464 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
| 3465 STATIC_ASSERT(kSmiTag == 0); | |
| 3466 STATIC_ASSERT(kSmiTagSize == 1); | |
| 3467 __ mov(r4, Operand(r4, LSL, kPointerSizeLog2 + 1)); | |
| 3468 __ Push(r2, r4); | |
| 3469 __ CallRuntime(Runtime::kAllocateInNewSpace); | |
| 3470 __ Pop(r2); | |
| 3471 } | |
| 3472 __ ldrb(r5, FieldMemOperand(r2, Map::kInstanceSizeOffset)); | |
| 3473 __ add(r5, r0, Operand(r5, LSL, kPointerSizeLog2)); | |
| 3474 STATIC_ASSERT(kHeapObjectTag == 1); | |
| 3475 __ sub(r5, r5, Operand(kHeapObjectTag)); | |
| 3476 __ b(&done_allocate); | |
| 3477 | |
| 3478 // Fall back to %NewObject. | |
| 3479 __ bind(&new_object); | |
| 3480 __ Push(r1, r3); | |
| 3481 __ TailCallRuntime(Runtime::kNewObject); | |
| 3482 } | |
| 3483 | |
| 3484 | |
| 3485 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { | 3368 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
| 3486 // ----------- S t a t e ------------- | 3369 // ----------- S t a t e ------------- |
| 3487 // -- r1 : function | 3370 // -- r1 : function |
| 3488 // -- cp : context | 3371 // -- cp : context |
| 3489 // -- fp : frame pointer | 3372 // -- fp : frame pointer |
| 3490 // -- lr : return address | 3373 // -- lr : return address |
| 3491 // ----------------------------------- | 3374 // ----------------------------------- |
| 3492 __ AssertFunction(r1); | 3375 __ AssertFunction(r1); |
| 3493 | 3376 |
| 3494 // Make r2 point to the JavaScript frame. | 3377 // Make r2 point to the JavaScript frame. |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4278 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, | 4161 CallApiFunctionAndReturn(masm, api_function_address, thunk_ref, |
| 4279 kStackUnwindSpace, NULL, return_value_operand, NULL); | 4162 kStackUnwindSpace, NULL, return_value_operand, NULL); |
| 4280 } | 4163 } |
| 4281 | 4164 |
| 4282 #undef __ | 4165 #undef __ |
| 4283 | 4166 |
| 4284 } // namespace internal | 4167 } // namespace internal |
| 4285 } // namespace v8 | 4168 } // namespace v8 |
| 4286 | 4169 |
| 4287 #endif // V8_TARGET_ARCH_ARM | 4170 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |