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 |