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_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 } | 270 } |
271 | 271 |
272 // Allocate the new receiver object using the runtime call. | 272 // Allocate the new receiver object using the runtime call. |
273 // rdx: original constructor | 273 // rdx: original constructor |
274 __ bind(&rt_call); | 274 __ bind(&rt_call); |
275 int offset = kPointerSize; | 275 int offset = kPointerSize; |
276 | 276 |
277 // Must restore rsi (context) and rdi (constructor) before calling runtime. | 277 // Must restore rsi (context) and rdi (constructor) before calling runtime. |
278 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 278 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
279 __ movp(rdi, Operand(rsp, offset)); | 279 __ movp(rdi, Operand(rsp, offset)); |
280 __ Push(rdi); // argument 2/1: constructor function | 280 __ Push(rdi); // constructor function |
281 __ Push(rdx); // argument 3/2: original constructor | 281 __ Push(rdx); // original constructor |
282 __ CallRuntime(Runtime::kNewObject, 2); | 282 __ CallRuntime(Runtime::kNewObject, 2); |
283 __ movp(rbx, rax); // store result in rbx | 283 __ movp(rbx, rax); // store result in rbx |
284 | 284 |
285 // New object allocated. | 285 // New object allocated. |
286 // rbx: newly allocated object | 286 // rbx: newly allocated object |
287 __ bind(&allocated); | 287 __ bind(&allocated); |
288 | 288 |
289 // Restore the parameters. | 289 // Restore the parameters. |
290 __ Pop(rdx); | 290 __ Pop(rdx); |
291 __ Pop(rdi); | 291 __ Pop(rdi); |
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); | 1416 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); |
1417 } | 1417 } |
1418 } | 1418 } |
1419 | 1419 |
1420 | 1420 |
1421 // static | 1421 // static |
1422 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1422 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
1423 // ----------- S t a t e ------------- | 1423 // ----------- S t a t e ------------- |
1424 // -- rax : number of arguments | 1424 // -- rax : number of arguments |
1425 // -- rdi : constructor function | 1425 // -- rdi : constructor function |
| 1426 // -- rdx : original constructor |
1426 // -- rsp[0] : return address | 1427 // -- rsp[0] : return address |
1427 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1428 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1428 // -- rsp[(argc + 1) * 8] : receiver | 1429 // -- rsp[(argc + 1) * 8] : receiver |
1429 // ----------------------------------- | 1430 // ----------------------------------- |
1430 | 1431 |
1431 // 1. Load the first argument into rbx and get rid of the rest (including the | 1432 // 1. Load the first argument into rbx and get rid of the rest (including the |
1432 // receiver). | 1433 // receiver). |
1433 { | 1434 { |
1434 StackArgumentsAccessor args(rsp, rax); | 1435 StackArgumentsAccessor args(rsp, rax); |
1435 Label no_arguments, done; | 1436 Label no_arguments, done; |
1436 __ testp(rax, rax); | 1437 __ testp(rax, rax); |
1437 __ j(zero, &no_arguments, Label::kNear); | 1438 __ j(zero, &no_arguments, Label::kNear); |
1438 __ movp(rbx, args.GetArgumentOperand(1)); | 1439 __ movp(rbx, args.GetArgumentOperand(1)); |
1439 __ jmp(&done, Label::kNear); | 1440 __ jmp(&done, Label::kNear); |
1440 __ bind(&no_arguments); | 1441 __ bind(&no_arguments); |
1441 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); | 1442 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); |
1442 __ bind(&done); | 1443 __ bind(&done); |
1443 __ PopReturnAddressTo(rcx); | 1444 __ PopReturnAddressTo(rcx); |
1444 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); | 1445 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); |
1445 __ PushReturnAddressFrom(rcx); | 1446 __ PushReturnAddressFrom(rcx); |
1446 } | 1447 } |
1447 | 1448 |
1448 // 2. Make sure rbx is a string. | 1449 // 2. Make sure rbx is a string. |
1449 { | 1450 { |
1450 Label convert, done_convert; | 1451 Label convert, done_convert; |
1451 __ JumpIfSmi(rbx, &convert, Label::kNear); | 1452 __ JumpIfSmi(rbx, &convert, Label::kNear); |
1452 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rdx); | 1453 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rcx); |
1453 __ j(below, &done_convert); | 1454 __ j(below, &done_convert); |
1454 __ bind(&convert); | 1455 __ bind(&convert); |
1455 { | 1456 { |
1456 FrameScope scope(masm, StackFrame::INTERNAL); | 1457 FrameScope scope(masm, StackFrame::INTERNAL); |
1457 ToStringStub stub(masm->isolate()); | 1458 ToStringStub stub(masm->isolate()); |
| 1459 __ Push(rdx); |
1458 __ Push(rdi); | 1460 __ Push(rdi); |
1459 __ Move(rax, rbx); | 1461 __ Move(rax, rbx); |
1460 __ CallStub(&stub); | 1462 __ CallStub(&stub); |
1461 __ Move(rbx, rax); | 1463 __ Move(rbx, rax); |
1462 __ Pop(rdi); | 1464 __ Pop(rdi); |
| 1465 __ Pop(rdx); |
1463 } | 1466 } |
1464 __ bind(&done_convert); | 1467 __ bind(&done_convert); |
1465 } | 1468 } |
1466 | 1469 |
1467 // 3. Allocate a JSValue wrapper for the string. | 1470 // 3. Allocate a JSValue wrapper for the string. |
1468 { | 1471 { |
1469 // ----------- S t a t e ------------- | 1472 // ----------- S t a t e ------------- |
1470 // -- rbx : the first argument | 1473 // -- rbx : the first argument |
1471 // -- rdi : constructor function | 1474 // -- rdi : constructor function |
| 1475 // -- rdx : original constructor |
1472 // ----------------------------------- | 1476 // ----------------------------------- |
| 1477 Label allocate, done_allocate, rt_call; |
1473 | 1478 |
1474 Label allocate, done_allocate; | 1479 // Fall back to runtime if the original constructor and constructor differ. |
| 1480 __ cmpp(rdx, rdi); |
| 1481 __ j(not_equal, &rt_call); |
| 1482 |
1475 __ Allocate(JSValue::kSize, rax, rcx, no_reg, &allocate, TAG_OBJECT); | 1483 __ Allocate(JSValue::kSize, rax, rcx, no_reg, &allocate, TAG_OBJECT); |
1476 __ bind(&done_allocate); | 1484 __ bind(&done_allocate); |
1477 | 1485 |
1478 // Initialize the JSValue in rax. | 1486 // Initialize the JSValue in rax. |
1479 __ LoadGlobalFunctionInitialMap(rdi, rcx); | 1487 __ LoadGlobalFunctionInitialMap(rdi, rcx); |
1480 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx); | 1488 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx); |
1481 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); | 1489 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); |
1482 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx); | 1490 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx); |
1483 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx); | 1491 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx); |
1484 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); | 1492 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); |
1485 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 1493 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
1486 __ Ret(); | 1494 __ Ret(); |
1487 | 1495 |
1488 // Fallback to the runtime to allocate in new space. | 1496 // Fallback to the runtime to allocate in new space. |
1489 __ bind(&allocate); | 1497 __ bind(&allocate); |
1490 { | 1498 { |
1491 FrameScope scope(masm, StackFrame::INTERNAL); | 1499 FrameScope scope(masm, StackFrame::INTERNAL); |
1492 __ Push(rbx); | 1500 __ Push(rbx); |
1493 __ Push(rdi); | 1501 __ Push(rdi); |
1494 __ Push(Smi::FromInt(JSValue::kSize)); | 1502 __ Push(Smi::FromInt(JSValue::kSize)); |
1495 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 1503 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
1496 __ Pop(rdi); | 1504 __ Pop(rdi); |
1497 __ Pop(rbx); | 1505 __ Pop(rbx); |
1498 } | 1506 } |
1499 __ jmp(&done_allocate); | 1507 __ jmp(&done_allocate); |
| 1508 |
| 1509 // Fallback to the runtime to create new object. |
| 1510 __ bind(&rt_call); |
| 1511 { |
| 1512 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1513 __ Push(rbx); |
| 1514 __ Push(rdi); |
| 1515 __ Push(rdi); // constructor function |
| 1516 __ Push(rdx); // original constructor |
| 1517 __ CallRuntime(Runtime::kNewObject, 2); |
| 1518 __ Pop(rdi); |
| 1519 __ Pop(rbx); |
| 1520 } |
| 1521 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); |
| 1522 __ Ret(); |
1500 } | 1523 } |
1501 } | 1524 } |
1502 | 1525 |
1503 | 1526 |
1504 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1527 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
1505 Label* stack_overflow) { | 1528 Label* stack_overflow) { |
1506 // ----------- S t a t e ------------- | 1529 // ----------- S t a t e ------------- |
1507 // -- rax : actual number of arguments | 1530 // -- rax : actual number of arguments |
1508 // -- rbx : expected number of arguments | 1531 // -- rbx : expected number of arguments |
1509 // -- rdi: function (passed through to callee) | 1532 // -- rdi: function (passed through to callee) |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1969 __ ret(0); | 1992 __ ret(0); |
1970 } | 1993 } |
1971 | 1994 |
1972 | 1995 |
1973 #undef __ | 1996 #undef __ |
1974 | 1997 |
1975 } // namespace internal | 1998 } // namespace internal |
1976 } // namespace v8 | 1999 } // namespace v8 |
1977 | 2000 |
1978 #endif // V8_TARGET_ARCH_X64 | 2001 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |