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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
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/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 3250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3261 | 3261 |
3262 Label fast_elements_case; | 3262 Label fast_elements_case; |
3263 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); | 3263 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); |
3264 __ j(equal, &fast_elements_case); | 3264 __ j(equal, &fast_elements_case); |
3265 GenerateCase(masm, FAST_HOLEY_ELEMENTS); | 3265 GenerateCase(masm, FAST_HOLEY_ELEMENTS); |
3266 | 3266 |
3267 __ bind(&fast_elements_case); | 3267 __ bind(&fast_elements_case); |
3268 GenerateCase(masm, FAST_ELEMENTS); | 3268 GenerateCase(masm, FAST_ELEMENTS); |
3269 } | 3269 } |
3270 | 3270 |
3271 | |
3272 void FastNewObjectStub::Generate(MacroAssembler* masm) { | |
3273 // ----------- S t a t e ------------- | |
3274 // -- rdi : target | |
3275 // -- rdx : new target | |
3276 // -- rsi : context | |
3277 // -- rsp[0] : return address | |
3278 // ----------------------------------- | |
3279 __ AssertFunction(rdi); | |
3280 __ AssertReceiver(rdx); | |
3281 | |
3282 // Verify that the new target is a JSFunction. | |
3283 Label new_object; | |
3284 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rbx); | |
3285 __ j(not_equal, &new_object); | |
3286 | |
3287 // Load the initial map and verify that it's in fact a map. | |
3288 __ movp(rcx, FieldOperand(rdx, JSFunction::kPrototypeOrInitialMapOffset)); | |
3289 __ JumpIfSmi(rcx, &new_object); | |
3290 __ CmpObjectType(rcx, MAP_TYPE, rbx); | |
3291 __ j(not_equal, &new_object); | |
3292 | |
3293 // Fall back to runtime if the target differs from the new target's | |
3294 // initial map constructor. | |
3295 __ cmpp(rdi, FieldOperand(rcx, Map::kConstructorOrBackPointerOffset)); | |
3296 __ j(not_equal, &new_object); | |
3297 | |
3298 // Allocate the JSObject on the heap. | |
3299 Label allocate, done_allocate; | |
3300 __ movzxbl(rbx, FieldOperand(rcx, Map::kInstanceSizeOffset)); | |
3301 __ leal(rbx, Operand(rbx, times_pointer_size, 0)); | |
3302 __ Allocate(rbx, rax, rdi, no_reg, &allocate, NO_ALLOCATION_FLAGS); | |
3303 __ bind(&done_allocate); | |
3304 | |
3305 // Initialize the JSObject fields. | |
3306 __ movp(FieldOperand(rax, JSObject::kMapOffset), rcx); | |
3307 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); | |
3308 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); | |
3309 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rbx); | |
3310 STATIC_ASSERT(JSObject::kHeaderSize == 3 * kPointerSize); | |
3311 __ leap(rbx, FieldOperand(rax, JSObject::kHeaderSize)); | |
3312 | |
3313 // ----------- S t a t e ------------- | |
3314 // -- rax : result (tagged) | |
3315 // -- rbx : result fields (untagged) | |
3316 // -- rdi : result end (untagged) | |
3317 // -- rcx : initial map | |
3318 // -- rsi : context | |
3319 // -- rsp[0] : return address | |
3320 // ----------------------------------- | |
3321 | |
3322 // Perform in-object slack tracking if requested. | |
3323 Label slack_tracking; | |
3324 STATIC_ASSERT(Map::kNoSlackTracking == 0); | |
3325 __ LoadRoot(r11, Heap::kUndefinedValueRootIndex); | |
3326 __ testl(FieldOperand(rcx, Map::kBitField3Offset), | |
3327 Immediate(Map::ConstructionCounter::kMask)); | |
3328 __ j(not_zero, &slack_tracking, Label::kNear); | |
3329 { | |
3330 // Initialize all in-object fields with undefined. | |
3331 __ InitializeFieldsWithFiller(rbx, rdi, r11); | |
3332 __ Ret(); | |
3333 } | |
3334 __ bind(&slack_tracking); | |
3335 { | |
3336 // Decrease generous allocation count. | |
3337 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); | |
3338 __ subl(FieldOperand(rcx, Map::kBitField3Offset), | |
3339 Immediate(1 << Map::ConstructionCounter::kShift)); | |
3340 | |
3341 // Initialize the in-object fields with undefined. | |
3342 __ movzxbl(rdx, FieldOperand(rcx, Map::kUnusedPropertyFieldsOffset)); | |
3343 __ negp(rdx); | |
3344 __ leap(rdx, Operand(rdi, rdx, times_pointer_size, 0)); | |
3345 __ InitializeFieldsWithFiller(rbx, rdx, r11); | |
3346 | |
3347 // Initialize the remaining (reserved) fields with one pointer filler map. | |
3348 __ LoadRoot(r11, Heap::kOnePointerFillerMapRootIndex); | |
3349 __ InitializeFieldsWithFiller(rdx, rdi, r11); | |
3350 | |
3351 // Check if we can finalize the instance size. | |
3352 Label finalize; | |
3353 STATIC_ASSERT(Map::kSlackTrackingCounterEnd == 1); | |
3354 __ testl(FieldOperand(rcx, Map::kBitField3Offset), | |
3355 Immediate(Map::ConstructionCounter::kMask)); | |
3356 __ j(zero, &finalize, Label::kNear); | |
3357 __ Ret(); | |
3358 | |
3359 // Finalize the instance size. | |
3360 __ bind(&finalize); | |
3361 { | |
3362 FrameScope scope(masm, StackFrame::INTERNAL); | |
3363 __ Push(rax); | |
3364 __ Push(rcx); | |
3365 __ CallRuntime(Runtime::kFinalizeInstanceSize); | |
3366 __ Pop(rax); | |
3367 } | |
3368 __ Ret(); | |
3369 } | |
3370 | |
3371 // Fall back to %AllocateInNewSpace. | |
3372 __ bind(&allocate); | |
3373 { | |
3374 FrameScope scope(masm, StackFrame::INTERNAL); | |
3375 __ Integer32ToSmi(rbx, rbx); | |
3376 __ Push(rcx); | |
3377 __ Push(rbx); | |
3378 __ CallRuntime(Runtime::kAllocateInNewSpace); | |
3379 __ Pop(rcx); | |
3380 } | |
3381 __ movzxbl(rbx, FieldOperand(rcx, Map::kInstanceSizeOffset)); | |
3382 __ leap(rdi, Operand(rax, rbx, times_pointer_size, 0)); | |
3383 STATIC_ASSERT(kHeapObjectTag == 1); | |
3384 __ decp(rdi); // Remove the tag from the end address. | |
3385 __ jmp(&done_allocate); | |
3386 | |
3387 // Fall back to %NewObject. | |
3388 __ bind(&new_object); | |
3389 __ PopReturnAddressTo(rcx); | |
3390 __ Push(rdi); | |
3391 __ Push(rdx); | |
3392 __ PushReturnAddressFrom(rcx); | |
3393 __ TailCallRuntime(Runtime::kNewObject); | |
3394 } | |
3395 | |
3396 | |
3397 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { | 3271 void FastNewRestParameterStub::Generate(MacroAssembler* masm) { |
3398 // ----------- S t a t e ------------- | 3272 // ----------- S t a t e ------------- |
3399 // -- rdi : function | 3273 // -- rdi : function |
3400 // -- rsi : context | 3274 // -- rsi : context |
3401 // -- rbp : frame pointer | 3275 // -- rbp : frame pointer |
3402 // -- rsp[0] : return address | 3276 // -- rsp[0] : return address |
3403 // ----------------------------------- | 3277 // ----------------------------------- |
3404 __ AssertFunction(rdi); | 3278 __ AssertFunction(rdi); |
3405 | 3279 |
3406 // Make rdx point to the JavaScript frame. | 3280 // Make rdx point to the JavaScript frame. |
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4303 kStackUnwindSpace, nullptr, return_value_operand, | 4177 kStackUnwindSpace, nullptr, return_value_operand, |
4304 NULL); | 4178 NULL); |
4305 } | 4179 } |
4306 | 4180 |
4307 #undef __ | 4181 #undef __ |
4308 | 4182 |
4309 } // namespace internal | 4183 } // namespace internal |
4310 } // namespace v8 | 4184 } // namespace v8 |
4311 | 4185 |
4312 #endif // V8_TARGET_ARCH_X64 | 4186 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |