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 1414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1425 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); | 1425 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1, 1); |
1426 } | 1426 } |
1427 } | 1427 } |
1428 | 1428 |
1429 | 1429 |
1430 // static | 1430 // static |
1431 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1431 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
1432 // ----------- S t a t e ------------- | 1432 // ----------- S t a t e ------------- |
1433 // -- rax : number of arguments | 1433 // -- rax : number of arguments |
1434 // -- rdi : constructor function | 1434 // -- rdi : constructor function |
1435 // -- rdx : original constructor | |
1435 // -- rsp[0] : return address | 1436 // -- rsp[0] : return address |
1436 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1437 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1437 // -- rsp[(argc + 1) * 8] : receiver | 1438 // -- rsp[(argc + 1) * 8] : receiver |
1438 // ----------------------------------- | 1439 // ----------------------------------- |
1439 | 1440 |
1440 // 1. Load the first argument into rbx and get rid of the rest (including the | 1441 // 1. Load the first argument into rbx and get rid of the rest (including the |
1441 // receiver). | 1442 // receiver). |
1442 { | 1443 { |
1443 StackArgumentsAccessor args(rsp, rax); | 1444 StackArgumentsAccessor args(rsp, rax); |
1444 Label no_arguments, done; | 1445 Label no_arguments, done; |
1445 __ testp(rax, rax); | 1446 __ testp(rax, rax); |
1446 __ j(zero, &no_arguments, Label::kNear); | 1447 __ j(zero, &no_arguments, Label::kNear); |
1447 __ movp(rbx, args.GetArgumentOperand(1)); | 1448 __ movp(rbx, args.GetArgumentOperand(1)); |
1448 __ jmp(&done, Label::kNear); | 1449 __ jmp(&done, Label::kNear); |
1449 __ bind(&no_arguments); | 1450 __ bind(&no_arguments); |
1450 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); | 1451 __ LoadRoot(rbx, Heap::kempty_stringRootIndex); |
1451 __ bind(&done); | 1452 __ bind(&done); |
1452 __ PopReturnAddressTo(rcx); | 1453 __ PopReturnAddressTo(rcx); |
1453 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); | 1454 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); |
1454 __ PushReturnAddressFrom(rcx); | 1455 __ PushReturnAddressFrom(rcx); |
1455 } | 1456 } |
1456 | 1457 |
1457 // 2. Make sure rbx is a string. | 1458 // 2. Make sure rbx is a string. |
1458 { | 1459 { |
1459 Label convert, done_convert; | 1460 Label convert, done_convert; |
1460 __ JumpIfSmi(rbx, &convert, Label::kNear); | 1461 __ JumpIfSmi(rbx, &convert, Label::kNear); |
1461 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rdx); | 1462 __ CmpObjectType(rbx, FIRST_NONSTRING_TYPE, rcx); |
1462 __ j(below, &done_convert); | 1463 __ j(below, &done_convert); |
1463 __ bind(&convert); | 1464 __ bind(&convert); |
1464 { | 1465 { |
1465 FrameScope scope(masm, StackFrame::INTERNAL); | 1466 FrameScope scope(masm, StackFrame::INTERNAL); |
1466 ToStringStub stub(masm->isolate()); | 1467 ToStringStub stub(masm->isolate()); |
1468 __ Push(rdx); | |
1467 __ Push(rdi); | 1469 __ Push(rdi); |
1468 __ Move(rax, rbx); | 1470 __ Move(rax, rbx); |
1469 __ CallStub(&stub); | 1471 __ CallStub(&stub); |
1470 __ Move(rbx, rax); | 1472 __ Move(rbx, rax); |
1471 __ Pop(rdi); | 1473 __ Pop(rdi); |
1474 __ Pop(rdx); | |
1472 } | 1475 } |
1473 __ bind(&done_convert); | 1476 __ bind(&done_convert); |
1474 } | 1477 } |
1475 | 1478 |
1476 // 3. Allocate a JSValue wrapper for the string. | 1479 // 3. Allocate a JSValue wrapper for the string. |
1477 { | 1480 { |
1478 // ----------- S t a t e ------------- | 1481 // ----------- S t a t e ------------- |
1479 // -- rbx : the first argument | 1482 // -- rbx : the first argument |
1480 // -- rdi : constructor function | 1483 // -- rdi : constructor function |
1484 // -- rdx : original constructor | |
1481 // ----------------------------------- | 1485 // ----------------------------------- |
1486 Label allocate, done_allocate, rt_call; | |
1482 | 1487 |
1483 Label allocate, done_allocate; | 1488 // Fall back to runtime if the original constructor and constructor differ. |
1489 __ cmpp(rdx, rdi); | |
1490 __ j(not_equal, &rt_call); | |
1491 | |
1484 __ Allocate(JSValue::kSize, rax, rcx, no_reg, &allocate, TAG_OBJECT); | 1492 __ Allocate(JSValue::kSize, rax, rcx, no_reg, &allocate, TAG_OBJECT); |
1485 __ bind(&done_allocate); | 1493 __ bind(&done_allocate); |
1486 | 1494 |
1487 // Initialize the JSValue in rax. | 1495 // Initialize the JSValue in rax. |
1488 __ LoadGlobalFunctionInitialMap(rdi, rcx); | 1496 __ LoadGlobalFunctionInitialMap(rdi, rcx); |
1489 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx); | 1497 __ movp(FieldOperand(rax, HeapObject::kMapOffset), rcx); |
1490 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); | 1498 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex); |
1491 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx); | 1499 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), rcx); |
1492 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx); | 1500 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rcx); |
1493 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); | 1501 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); |
1494 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 1502 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
1495 __ Ret(); | 1503 __ Ret(); |
1496 | 1504 |
1497 // Fallback to the runtime to allocate in new space. | 1505 // Fallback to the runtime to allocate in new space. |
1498 __ bind(&allocate); | 1506 __ bind(&allocate); |
1499 { | 1507 { |
1500 FrameScope scope(masm, StackFrame::INTERNAL); | 1508 FrameScope scope(masm, StackFrame::INTERNAL); |
1501 __ Push(rbx); | 1509 __ Push(rbx); |
1502 __ Push(rdi); | 1510 __ Push(rdi); |
1503 __ Push(Smi::FromInt(JSValue::kSize)); | 1511 __ Push(Smi::FromInt(JSValue::kSize)); |
1504 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); | 1512 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); |
1505 __ Pop(rdi); | 1513 __ Pop(rdi); |
1506 __ Pop(rbx); | 1514 __ Pop(rbx); |
1507 } | 1515 } |
1508 __ jmp(&done_allocate); | 1516 __ jmp(&done_allocate); |
1517 | |
1518 // Fallback to the runtime to create new object. | |
1519 __ bind(&rt_call); | |
1520 { | |
1521 FrameScope scope(masm, StackFrame::INTERNAL); | |
1522 __ Push(rbx); | |
1523 __ Push(rdi); | |
1524 __ Push(rdi); // argument 2/1: constructor function | |
Toon Verwaest
2015/10/26 15:10:57
I don't understand 2/1, 3/2...
Igor Sheludko
2015/10/27 12:56:12
Done.
| |
1525 __ Push(rdx); // argument 3/2: original constructor | |
1526 // TODO(ishell): allocation site? | |
1527 __ CallRuntime(Runtime::kNewObject, 2); | |
Toon Verwaest
2015/10/26 15:10:57
Please add some tests here that subclassing now wo
Igor Sheludko
2015/10/27 12:56:12
Done.
| |
1528 __ Pop(rdi); | |
1529 __ Pop(rbx); | |
1530 } | |
1531 __ movp(FieldOperand(rax, JSValue::kValueOffset), rbx); | |
1532 __ Ret(); | |
1509 } | 1533 } |
1510 } | 1534 } |
1511 | 1535 |
1512 | 1536 |
1513 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1537 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
1514 Label* stack_overflow) { | 1538 Label* stack_overflow) { |
1515 // ----------- S t a t e ------------- | 1539 // ----------- S t a t e ------------- |
1516 // -- rax : actual number of arguments | 1540 // -- rax : actual number of arguments |
1517 // -- rbx : expected number of arguments | 1541 // -- rbx : expected number of arguments |
1518 // -- rdi: function (passed through to callee) | 1542 // -- rdi: function (passed through to callee) |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1978 __ ret(0); | 2002 __ ret(0); |
1979 } | 2003 } |
1980 | 2004 |
1981 | 2005 |
1982 #undef __ | 2006 #undef __ |
1983 | 2007 |
1984 } // namespace internal | 2008 } // namespace internal |
1985 } // namespace v8 | 2009 } // namespace v8 |
1986 | 2010 |
1987 #endif // V8_TARGET_ARCH_X64 | 2011 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |