Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(435)

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 void MacroAssembler::PushRoot(Heap::RootListIndex index) { 61 void MacroAssembler::PushRoot(Heap::RootListIndex index) {
62 push(Operand(kRootRegister, index << kPointerSizeLog2)); 62 push(Operand(kRootRegister, index << kPointerSizeLog2));
63 } 63 }
64 64
65 65
66 void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 66 void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
67 cmpq(with, Operand(kRootRegister, index << kPointerSizeLog2)); 67 cmpq(with, Operand(kRootRegister, index << kPointerSizeLog2));
68 } 68 }
69 69
70 70
71 void MacroAssembler::CompareRoot(Operand with, Heap::RootListIndex index) { 71 void MacroAssembler::CompareRoot(const Operand& with,
72 Heap::RootListIndex index) {
73 ASSERT(!with.AddressUsesRegister(kScratchRegister));
72 LoadRoot(kScratchRegister, index); 74 LoadRoot(kScratchRegister, index);
73 cmpq(with, kScratchRegister); 75 cmpq(with, kScratchRegister);
74 } 76 }
75 77
76 78
77 void MacroAssembler::RecordWriteHelper(Register object, 79 void MacroAssembler::RecordWriteHelper(Register object,
78 Register addr, 80 Register addr,
79 Register scratch, 81 Register scratch,
80 SaveFPRegsMode save_fp) { 82 SaveFPRegsMode save_fp) {
81 if (FLAG_debug_code) { 83 if (FLAG_debug_code) {
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag; 294 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
293 // Note: p0 might not be a valid Smi *value*, but it has a valid Smi tag. 295 // Note: p0 might not be a valid Smi *value*, but it has a valid Smi tag.
294 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi()); 296 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
295 #ifdef DEBUG 297 #ifdef DEBUG
296 if (msg != NULL) { 298 if (msg != NULL) {
297 RecordComment("Abort message: "); 299 RecordComment("Abort message: ");
298 RecordComment(msg); 300 RecordComment(msg);
299 } 301 }
300 #endif 302 #endif
301 // Disable stub call restrictions to always allow calls to abort. 303 // Disable stub call restrictions to always allow calls to abort.
302 set_allow_stub_calls(true); 304 AllowStubCallsScope allow_scope(this, true);
303 305
304 push(rax); 306 push(rax);
305 movq(kScratchRegister, p0, RelocInfo::NONE); 307 movq(kScratchRegister, p0, RelocInfo::NONE);
306 push(kScratchRegister); 308 push(kScratchRegister);
307 movq(kScratchRegister, 309 movq(kScratchRegister,
308 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(p1 - p0))), 310 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(p1 - p0))),
309 RelocInfo::NONE); 311 RelocInfo::NONE);
310 push(kScratchRegister); 312 push(kScratchRegister);
311 CallRuntime(Runtime::kAbort, 2); 313 CallRuntime(Runtime::kAbort, 2);
312 // will not return here 314 // will not return here
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 // there is no difference in using either key. 381 // there is no difference in using either key.
380 Integer32ToSmi(index, hash); 382 Integer32ToSmi(index, hash);
381 } 383 }
382 384
383 385
384 void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) { 386 void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) {
385 CallRuntime(Runtime::FunctionForId(id), num_arguments); 387 CallRuntime(Runtime::FunctionForId(id), num_arguments);
386 } 388 }
387 389
388 390
391 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) {
392 Runtime::Function* function = Runtime::FunctionForId(id);
393 Set(rax, function->nargs);
394 movq(rbx, ExternalReference(function));
395 CEntryStub ces(1);
396 ces.SaveDoubles();
397 CallStub(&ces);
398 }
399
400
389 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id, 401 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id,
390 int num_arguments) { 402 int num_arguments) {
391 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments); 403 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments);
392 } 404 }
393 405
394 406
395 void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) { 407 void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
396 // If the expected number of arguments of the runtime function is 408 // If the expected number of arguments of the runtime function is
397 // constant, we check that the actual number of arguments match the 409 // constant, we check that the actual number of arguments match the
398 // expectation. 410 // expectation.
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 } 901 }
890 902
891 903
892 Condition MacroAssembler::CheckSmi(Register src) { 904 Condition MacroAssembler::CheckSmi(Register src) {
893 ASSERT_EQ(0, kSmiTag); 905 ASSERT_EQ(0, kSmiTag);
894 testb(src, Immediate(kSmiTagMask)); 906 testb(src, Immediate(kSmiTagMask));
895 return zero; 907 return zero;
896 } 908 }
897 909
898 910
911 Condition MacroAssembler::CheckSmi(const Operand& src) {
912 ASSERT_EQ(0, kSmiTag);
913 testb(src, Immediate(kSmiTagMask));
914 return zero;
915 }
916
917
899 Condition MacroAssembler::CheckNonNegativeSmi(Register src) { 918 Condition MacroAssembler::CheckNonNegativeSmi(Register src) {
900 ASSERT_EQ(0, kSmiTag); 919 ASSERT_EQ(0, kSmiTag);
901 // Make mask 0x8000000000000001 and test that both bits are zero. 920 // Make mask 0x8000000000000001 and test that both bits are zero.
902 movq(kScratchRegister, src); 921 movq(kScratchRegister, src);
903 rol(kScratchRegister, Immediate(1)); 922 rol(kScratchRegister, Immediate(1));
904 testb(kScratchRegister, Immediate(3)); 923 testb(kScratchRegister, Immediate(3));
905 return zero; 924 return zero;
906 } 925 }
907 926
908 927
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
964 983
965 984
966 Condition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) { 985 Condition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) {
967 // An unsigned 32-bit integer value is valid as long as the high bit 986 // An unsigned 32-bit integer value is valid as long as the high bit
968 // is not set. 987 // is not set.
969 testl(src, src); 988 testl(src, src);
970 return positive; 989 return positive;
971 } 990 }
972 991
973 992
993 void MacroAssembler::CheckSmiToIndicator(Register dst, Register src) {
994 if (dst.is(src)) {
995 andl(dst, Immediate(kSmiTagMask));
996 } else {
997 movl(dst, Immediate(kSmiTagMask));
998 andl(dst, src);
999 }
1000 }
1001
1002
1003 void MacroAssembler::CheckSmiToIndicator(Register dst, const Operand& src) {
1004 if (!(src.AddressUsesRegister(dst))) {
1005 movl(dst, Immediate(kSmiTagMask));
1006 andl(dst, src);
1007 } else {
1008 movl(dst, src);
1009 andl(dst, Immediate(kSmiTagMask));
1010 }
1011 }
1012
1013
974 void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) { 1014 void MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) {
975 if (constant->value() == 0) { 1015 if (constant->value() == 0) {
976 if (!dst.is(src)) { 1016 if (!dst.is(src)) {
977 movq(dst, src); 1017 movq(dst, src);
978 } 1018 }
979 return; 1019 return;
980 } else if (dst.is(src)) { 1020 } else if (dst.is(src)) {
981 ASSERT(!dst.is(kScratchRegister)); 1021 ASSERT(!dst.is(kScratchRegister));
982 switch (constant->value()) { 1022 switch (constant->value()) {
983 case 1: 1023 case 1:
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 } 1318 }
1279 1319
1280 1320
1281 void MacroAssembler::Move(Register dst, Register src) { 1321 void MacroAssembler::Move(Register dst, Register src) {
1282 if (!dst.is(src)) { 1322 if (!dst.is(src)) {
1283 movq(dst, src); 1323 movq(dst, src);
1284 } 1324 }
1285 } 1325 }
1286 1326
1287 1327
1288
1289
1290 void MacroAssembler::Move(Register dst, Handle<Object> source) { 1328 void MacroAssembler::Move(Register dst, Handle<Object> source) {
1291 ASSERT(!source->IsFailure()); 1329 ASSERT(!source->IsFailure());
1292 if (source->IsSmi()) { 1330 if (source->IsSmi()) {
1293 Move(dst, Smi::cast(*source)); 1331 Move(dst, Smi::cast(*source));
1294 } else { 1332 } else {
1295 movq(dst, source, RelocInfo::EMBEDDED_OBJECT); 1333 movq(dst, source, RelocInfo::EMBEDDED_OBJECT);
1296 } 1334 }
1297 } 1335 }
1298 1336
1299 1337
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 call(kScratchRegister); 1430 call(kScratchRegister);
1393 } 1431 }
1394 1432
1395 1433
1396 void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) { 1434 void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
1397 ASSERT(RelocInfo::IsCodeTarget(rmode)); 1435 ASSERT(RelocInfo::IsCodeTarget(rmode));
1398 call(code_object, rmode); 1436 call(code_object, rmode);
1399 } 1437 }
1400 1438
1401 1439
1440 void MacroAssembler::Pushad() {
1441 push(rax);
1442 push(rcx);
1443 push(rdx);
1444 push(rbx);
1445 // Not pushing rsp or rbp.
1446 push(rsi);
1447 push(rdi);
1448 push(r8);
1449 push(r9);
1450 // r10 is kScratchRegister.
1451 push(r11);
1452 push(r12);
1453 // r13 is kRootRegister.
1454 push(r14);
1455 // r15 is kSmiConstantRegister
1456 STATIC_ASSERT(11 == kNumSafepointSavedRegisters);
1457 // Use lea for symmetry with Popad.
1458 lea(rsp, Operand(rsp,
1459 -(kNumSafepointRegisters-kNumSafepointSavedRegisters) * kPointerSize));
1460 }
1461
1462
1463 void MacroAssembler::Popad() {
1464 // Popad must not change the flags, so use lea instead of addq.
1465 lea(rsp, Operand(rsp,
1466 (kNumSafepointRegisters-kNumSafepointSavedRegisters) * kPointerSize));
1467 pop(r14);
1468 pop(r12);
1469 pop(r11);
1470 pop(r9);
1471 pop(r8);
1472 pop(rdi);
1473 pop(rsi);
1474 pop(rbx);
1475 pop(rdx);
1476 pop(rcx);
1477 pop(rax);
1478 }
1479
1480
1481 void MacroAssembler::Dropad() {
1482 addq(rsp, Immediate(kNumSafepointRegisters * kPointerSize));
1483 }
1484
1485
1486 // Order general registers are pushed by Pushad:
1487 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14.
1488 int MacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = {
1489 0,
1490 1,
1491 2,
1492 3,
1493 -1,
1494 -1,
1495 4,
1496 5,
1497 6,
1498 7,
1499 -1,
1500 8,
1501 9,
1502 -1,
1503 10,
1504 -1
1505 };
1506
1507
1402 void MacroAssembler::PushTryHandler(CodeLocation try_location, 1508 void MacroAssembler::PushTryHandler(CodeLocation try_location,
1403 HandlerType type) { 1509 HandlerType type) {
1404 // Adjust this code if not the case. 1510 // Adjust this code if not the case.
1405 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); 1511 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
1406 1512
1407 // The pc (return address) is already on TOS. This code pushes state, 1513 // The pc (return address) is already on TOS. This code pushes state,
1408 // frame pointer and current handler. Check that they are expected 1514 // frame pointer and current handler. Check that they are expected
1409 // next on the stack, in that order. 1515 // next on the stack, in that order.
1410 ASSERT_EQ(StackHandlerConstants::kStateOffset, 1516 ASSERT_EQ(StackHandlerConstants::kStateOffset,
1411 StackHandlerConstants::kPCOffset - kPointerSize); 1517 StackHandlerConstants::kPCOffset - kPointerSize);
(...skipping 28 matching lines...) Expand all
1440 void MacroAssembler::PopTryHandler() { 1546 void MacroAssembler::PopTryHandler() {
1441 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); 1547 ASSERT_EQ(0, StackHandlerConstants::kNextOffset);
1442 // Unlink this handler. 1548 // Unlink this handler.
1443 movq(kScratchRegister, ExternalReference(Top::k_handler_address)); 1549 movq(kScratchRegister, ExternalReference(Top::k_handler_address));
1444 pop(Operand(kScratchRegister, 0)); 1550 pop(Operand(kScratchRegister, 0));
1445 // Remove the remaining fields. 1551 // Remove the remaining fields.
1446 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 1552 addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
1447 } 1553 }
1448 1554
1449 1555
1556 void MacroAssembler::Throw(Register value) {
1557 // Check that stack should contain next handler, frame pointer, state and
1558 // return address in that order.
1559 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize ==
1560 StackHandlerConstants::kStateOffset);
1561 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize ==
1562 StackHandlerConstants::kPCOffset);
1563 // Keep thrown value in rax.
1564 if (!value.is(rax)) {
1565 movq(rax, value);
1566 }
1567
1568 ExternalReference handler_address(Top::k_handler_address);
1569 movq(kScratchRegister, handler_address);
1570 movq(rsp, Operand(kScratchRegister, 0));
1571 // get next in chain
1572 pop(rcx);
1573 movq(Operand(kScratchRegister, 0), rcx);
1574 pop(rbp); // pop frame pointer
1575 pop(rdx); // remove state
1576
1577 // Before returning we restore the context from the frame pointer if not NULL.
1578 // The frame pointer is NULL in the exception handler of a JS entry frame.
1579 Set(rsi, 0); // Tentatively set context pointer to NULL
1580 NearLabel skip;
1581 cmpq(rbp, Immediate(0));
1582 j(equal, &skip);
1583 movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
1584 bind(&skip);
1585 ret(0);
1586 }
1587
1588
1589 void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
1590 Register value) {
1591 // Keep thrown value in rax.
1592 if (!value.is(rax)) {
1593 movq(rax, value);
1594 }
1595 // Fetch top stack handler.
1596 ExternalReference handler_address(Top::k_handler_address);
1597 movq(kScratchRegister, handler_address);
1598 movq(rsp, Operand(kScratchRegister, 0));
1599
1600 // Unwind the handlers until the ENTRY handler is found.
1601 NearLabel loop, done;
1602 bind(&loop);
1603 // Load the type of the current stack handler.
1604 const int kStateOffset = StackHandlerConstants::kStateOffset;
1605 cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY));
1606 j(equal, &done);
1607 // Fetch the next handler in the list.
1608 const int kNextOffset = StackHandlerConstants::kNextOffset;
1609 movq(rsp, Operand(rsp, kNextOffset));
1610 jmp(&loop);
1611 bind(&done);
1612
1613 // Set the top handler address to next handler past the current ENTRY handler.
1614 movq(kScratchRegister, handler_address);
1615 pop(Operand(kScratchRegister, 0));
1616
1617 if (type == OUT_OF_MEMORY) {
1618 // Set external caught exception to false.
1619 ExternalReference external_caught(Top::k_external_caught_exception_address);
1620 movq(rax, Immediate(false));
1621 store_rax(external_caught);
1622
1623 // Set pending exception and rax to out of memory exception.
1624 ExternalReference pending_exception(Top::k_pending_exception_address);
1625 movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE);
1626 store_rax(pending_exception);
1627 }
1628
1629 // Clear the context pointer.
1630 Set(rsi, 0);
1631
1632 // Restore registers from handler.
1633 STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize ==
1634 StackHandlerConstants::kFPOffset);
1635 pop(rbp); // FP
1636 STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize ==
1637 StackHandlerConstants::kStateOffset);
1638 pop(rdx); // State
1639
1640 STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize ==
1641 StackHandlerConstants::kPCOffset);
1642 ret(0);
1643 }
1644
1645
1450 void MacroAssembler::Ret() { 1646 void MacroAssembler::Ret() {
1451 ret(0); 1647 ret(0);
1452 } 1648 }
1453 1649
1454 1650
1651 void MacroAssembler::Ret(int bytes_dropped, Register scratch) {
1652 if (is_uint16(bytes_dropped)) {
1653 ret(bytes_dropped);
1654 } else {
1655 pop(scratch);
1656 addq(rsp, Immediate(bytes_dropped));
1657 push(scratch);
1658 ret(0);
1659 }
1660 }
1661
1662
1455 void MacroAssembler::FCmp() { 1663 void MacroAssembler::FCmp() {
1456 fucomip(); 1664 fucomip();
1457 fstp(0); 1665 fstp(0);
1458 } 1666 }
1459 1667
1460 1668
1461 void MacroAssembler::CmpObjectType(Register heap_object, 1669 void MacroAssembler::CmpObjectType(Register heap_object,
1462 InstanceType type, 1670 InstanceType type,
1463 Register map) { 1671 Register map) {
1464 movq(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 1672 movq(map, FieldOperand(heap_object, HeapObject::kMapOffset));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 } 1710 }
1503 1711
1504 1712
1505 void MacroAssembler::AbortIfNotSmi(Register object) { 1713 void MacroAssembler::AbortIfNotSmi(Register object) {
1506 NearLabel ok; 1714 NearLabel ok;
1507 Condition is_smi = CheckSmi(object); 1715 Condition is_smi = CheckSmi(object);
1508 Assert(is_smi, "Operand is not a smi"); 1716 Assert(is_smi, "Operand is not a smi");
1509 } 1717 }
1510 1718
1511 1719
1720 void MacroAssembler::AbortIfNotString(Register object) {
1721 testb(object, Immediate(kSmiTagMask));
1722 Assert(not_equal, "Operand is not a string");
1723 push(object);
1724 movq(object, FieldOperand(object, HeapObject::kMapOffset));
1725 CmpInstanceType(object, FIRST_NONSTRING_TYPE);
1726 pop(object);
1727 Assert(below, "Operand is not a string");
1728 }
1729
1730
1512 void MacroAssembler::AbortIfNotRootValue(Register src, 1731 void MacroAssembler::AbortIfNotRootValue(Register src,
1513 Heap::RootListIndex root_value_index, 1732 Heap::RootListIndex root_value_index,
1514 const char* message) { 1733 const char* message) {
1515 ASSERT(!src.is(kScratchRegister)); 1734 ASSERT(!src.is(kScratchRegister));
1516 LoadRoot(kScratchRegister, root_value_index); 1735 LoadRoot(kScratchRegister, root_value_index);
1517 cmpq(src, kScratchRegister); 1736 cmpq(src, kScratchRegister);
1518 Check(equal, message); 1737 Check(equal, message);
1519 } 1738 }
1520 1739
1521 1740
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1676 1895
1677 1896
1678 void MacroAssembler::InvokeFunction(JSFunction* function, 1897 void MacroAssembler::InvokeFunction(JSFunction* function,
1679 const ParameterCount& actual, 1898 const ParameterCount& actual,
1680 InvokeFlag flag) { 1899 InvokeFlag flag) {
1681 ASSERT(function->is_compiled()); 1900 ASSERT(function->is_compiled());
1682 // Get the function and setup the context. 1901 // Get the function and setup the context.
1683 Move(rdi, Handle<JSFunction>(function)); 1902 Move(rdi, Handle<JSFunction>(function));
1684 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 1903 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
1685 1904
1686 // Invoke the cached code. 1905 if (V8::UseCrankshaft()) {
1687 Handle<Code> code(function->code()); 1906 // Since Crankshaft can recompile a function, we need to load
1688 ParameterCount expected(function->shared()->formal_parameter_count()); 1907 // the Code object every time we call the function.
1689 InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag); 1908 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
1909 ParameterCount expected(function->shared()->formal_parameter_count());
1910 InvokeCode(rdx, expected, actual, flag);
1911 } else {
1912 // Invoke the cached code.
1913 Handle<Code> code(function->code());
1914 ParameterCount expected(function->shared()->formal_parameter_count());
1915 InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag);
1916 }
1690 } 1917 }
1691 1918
1692 1919
1693 void MacroAssembler::EnterFrame(StackFrame::Type type) { 1920 void MacroAssembler::EnterFrame(StackFrame::Type type) {
1694 push(rbp); 1921 push(rbp);
1695 movq(rbp, rsp); 1922 movq(rbp, rsp);
1696 push(rsi); // Context. 1923 push(rsi); // Context.
1697 Push(Smi::FromInt(type)); 1924 Push(Smi::FromInt(type));
1698 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 1925 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
1699 push(kScratchRegister); 1926 push(kScratchRegister);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 movq(r14, rax); // Backup rax before we use it. 1967 movq(r14, rax); // Backup rax before we use it.
1741 } 1968 }
1742 1969
1743 movq(rax, rbp); 1970 movq(rax, rbp);
1744 store_rax(c_entry_fp_address); 1971 store_rax(c_entry_fp_address);
1745 movq(rax, rsi); 1972 movq(rax, rsi);
1746 store_rax(context_address); 1973 store_rax(context_address);
1747 } 1974 }
1748 1975
1749 1976
1750 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space) { 1977 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
1978 bool save_doubles) {
1751 #ifdef _WIN64 1979 #ifdef _WIN64
1752 const int kShaddowSpace = 4; 1980 const int kShadowSpace = 4;
1753 arg_stack_space += kShaddowSpace; 1981 arg_stack_space += kShadowSpace;
1754 #endif 1982 #endif
1755 if (arg_stack_space > 0) { 1983 // Optionally save all XMM registers.
1984 if (save_doubles) {
1985 CpuFeatures::Scope scope(SSE2);
1986 int space = XMMRegister::kNumRegisters * kDoubleSize +
1987 arg_stack_space * kPointerSize;
1988 subq(rsp, Immediate(space));
1989 int offset = -2 * kPointerSize;
1990 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; i++) {
1991 XMMRegister reg = XMMRegister::FromAllocationIndex(i);
1992 movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg);
1993 }
1994 } else if (arg_stack_space > 0) {
1756 subq(rsp, Immediate(arg_stack_space * kPointerSize)); 1995 subq(rsp, Immediate(arg_stack_space * kPointerSize));
1757 } 1996 }
1758 1997
1759 // Get the required frame alignment for the OS. 1998 // Get the required frame alignment for the OS.
1760 static const int kFrameAlignment = OS::ActivationFrameAlignment(); 1999 static const int kFrameAlignment = OS::ActivationFrameAlignment();
1761 if (kFrameAlignment > 0) { 2000 if (kFrameAlignment > 0) {
1762 ASSERT(IsPowerOf2(kFrameAlignment)); 2001 ASSERT(IsPowerOf2(kFrameAlignment));
1763 movq(kScratchRegister, Immediate(-kFrameAlignment)); 2002 movq(kScratchRegister, Immediate(-kFrameAlignment));
1764 and_(rsp, kScratchRegister); 2003 and_(rsp, kScratchRegister);
1765 } 2004 }
1766 2005
1767 // Patch the saved entry sp. 2006 // Patch the saved entry sp.
1768 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); 2007 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
1769 } 2008 }
1770 2009
1771 2010
1772 void MacroAssembler::EnterExitFrame(int arg_stack_space) { 2011 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) {
1773 EnterExitFramePrologue(true); 2012 EnterExitFramePrologue(true);
1774 2013
1775 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame, 2014 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
1776 // so it must be retained across the C-call. 2015 // so it must be retained across the C-call.
1777 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 2016 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
1778 lea(r12, Operand(rbp, r14, times_pointer_size, offset)); 2017 lea(r12, Operand(rbp, r14, times_pointer_size, offset));
1779 2018
1780 EnterExitFrameEpilogue(arg_stack_space); 2019 EnterExitFrameEpilogue(arg_stack_space, save_doubles);
1781 } 2020 }
1782 2021
1783 2022
1784 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) { 2023 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) {
1785 EnterExitFramePrologue(false); 2024 EnterExitFramePrologue(false);
1786 EnterExitFrameEpilogue(arg_stack_space); 2025 EnterExitFrameEpilogue(arg_stack_space, false);
1787 } 2026 }
1788 2027
1789 2028
1790 void MacroAssembler::LeaveExitFrame() { 2029 void MacroAssembler::LeaveExitFrame(bool save_doubles) {
1791 // Registers: 2030 // Registers:
1792 // r12 : argv 2031 // r12 : argv
1793 2032 if (save_doubles) {
2033 int offset = -2 * kPointerSize;
2034 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; i++) {
2035 XMMRegister reg = XMMRegister::FromAllocationIndex(i);
2036 movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize)));
2037 }
2038 }
1794 // Get the return address from the stack and restore the frame pointer. 2039 // Get the return address from the stack and restore the frame pointer.
1795 movq(rcx, Operand(rbp, 1 * kPointerSize)); 2040 movq(rcx, Operand(rbp, 1 * kPointerSize));
1796 movq(rbp, Operand(rbp, 0 * kPointerSize)); 2041 movq(rbp, Operand(rbp, 0 * kPointerSize));
1797 2042
1798 // Pop everything up to and including the arguments and the receiver 2043 // Drop everything up to and including the arguments and the receiver
1799 // from the caller stack. 2044 // from the caller stack.
1800 lea(rsp, Operand(r12, 1 * kPointerSize)); 2045 lea(rsp, Operand(r12, 1 * kPointerSize));
1801 2046
1802 // Push the return address to get ready to return. 2047 // Push the return address to get ready to return.
1803 push(rcx); 2048 push(rcx);
1804 2049
1805 LeaveExitFrameEpilogue(); 2050 LeaveExitFrameEpilogue();
1806 } 2051 }
1807 2052
1808 2053
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1976 2221
1977 // Load address of new object into result. 2222 // Load address of new object into result.
1978 LoadAllocationTopHelper(result, scratch, flags); 2223 LoadAllocationTopHelper(result, scratch, flags);
1979 2224
1980 // Calculate new top and bail out if new space is exhausted. 2225 // Calculate new top and bail out if new space is exhausted.
1981 ExternalReference new_space_allocation_limit = 2226 ExternalReference new_space_allocation_limit =
1982 ExternalReference::new_space_allocation_limit_address(); 2227 ExternalReference::new_space_allocation_limit_address();
1983 2228
1984 Register top_reg = result_end.is_valid() ? result_end : result; 2229 Register top_reg = result_end.is_valid() ? result_end : result;
1985 2230
1986 if (top_reg.is(result)) { 2231 if (!top_reg.is(result)) {
1987 addq(top_reg, Immediate(object_size)); 2232 movq(top_reg, result);
1988 } else {
1989 lea(top_reg, Operand(result, object_size));
1990 } 2233 }
2234 addq(top_reg, Immediate(object_size));
2235 j(carry, gc_required);
1991 movq(kScratchRegister, new_space_allocation_limit); 2236 movq(kScratchRegister, new_space_allocation_limit);
1992 cmpq(top_reg, Operand(kScratchRegister, 0)); 2237 cmpq(top_reg, Operand(kScratchRegister, 0));
1993 j(above, gc_required); 2238 j(above, gc_required);
1994 2239
1995 // Update allocation top. 2240 // Update allocation top.
1996 UpdateAllocationTopHelper(top_reg, scratch); 2241 UpdateAllocationTopHelper(top_reg, scratch);
1997 2242
1998 if (top_reg.is(result)) { 2243 if (top_reg.is(result)) {
1999 if ((flags & TAG_OBJECT) != 0) { 2244 if ((flags & TAG_OBJECT) != 0) {
2000 subq(result, Immediate(object_size - kHeapObjectTag)); 2245 subq(result, Immediate(object_size - kHeapObjectTag));
(...skipping 29 matching lines...) Expand all
2030 return; 2275 return;
2031 } 2276 }
2032 ASSERT(!result.is(result_end)); 2277 ASSERT(!result.is(result_end));
2033 2278
2034 // Load address of new object into result. 2279 // Load address of new object into result.
2035 LoadAllocationTopHelper(result, scratch, flags); 2280 LoadAllocationTopHelper(result, scratch, flags);
2036 2281
2037 // Calculate new top and bail out if new space is exhausted. 2282 // Calculate new top and bail out if new space is exhausted.
2038 ExternalReference new_space_allocation_limit = 2283 ExternalReference new_space_allocation_limit =
2039 ExternalReference::new_space_allocation_limit_address(); 2284 ExternalReference::new_space_allocation_limit_address();
2040 lea(result_end, Operand(result, element_count, element_size, header_size)); 2285
2286 // We assume that element_count*element_size + header_size does not
2287 // overflow.
2288 lea(result_end, Operand(element_count, element_size, header_size));
2289 addq(result_end, result);
2290 j(carry, gc_required);
2041 movq(kScratchRegister, new_space_allocation_limit); 2291 movq(kScratchRegister, new_space_allocation_limit);
2042 cmpq(result_end, Operand(kScratchRegister, 0)); 2292 cmpq(result_end, Operand(kScratchRegister, 0));
2043 j(above, gc_required); 2293 j(above, gc_required);
2044 2294
2045 // Update allocation top. 2295 // Update allocation top.
2046 UpdateAllocationTopHelper(result_end, scratch); 2296 UpdateAllocationTopHelper(result_end, scratch);
2047 2297
2048 // Tag the result if requested. 2298 // Tag the result if requested.
2049 if ((flags & TAG_OBJECT) != 0) { 2299 if ((flags & TAG_OBJECT) != 0) {
2050 addq(result, Immediate(kHeapObjectTag)); 2300 addq(result, Immediate(kHeapObjectTag));
(...skipping 25 matching lines...) Expand all
2076 // Load address of new object into result. 2326 // Load address of new object into result.
2077 LoadAllocationTopHelper(result, scratch, flags); 2327 LoadAllocationTopHelper(result, scratch, flags);
2078 2328
2079 // Calculate new top and bail out if new space is exhausted. 2329 // Calculate new top and bail out if new space is exhausted.
2080 ExternalReference new_space_allocation_limit = 2330 ExternalReference new_space_allocation_limit =
2081 ExternalReference::new_space_allocation_limit_address(); 2331 ExternalReference::new_space_allocation_limit_address();
2082 if (!object_size.is(result_end)) { 2332 if (!object_size.is(result_end)) {
2083 movq(result_end, object_size); 2333 movq(result_end, object_size);
2084 } 2334 }
2085 addq(result_end, result); 2335 addq(result_end, result);
2336 j(carry, gc_required);
2086 movq(kScratchRegister, new_space_allocation_limit); 2337 movq(kScratchRegister, new_space_allocation_limit);
2087 cmpq(result_end, Operand(kScratchRegister, 0)); 2338 cmpq(result_end, Operand(kScratchRegister, 0));
2088 j(above, gc_required); 2339 j(above, gc_required);
2089 2340
2090 // Update allocation top. 2341 // Update allocation top.
2091 UpdateAllocationTopHelper(result_end, scratch); 2342 UpdateAllocationTopHelper(result_end, scratch);
2092 2343
2093 // Tag the result if requested. 2344 // Tag the result if requested.
2094 if ((flags & TAG_OBJECT) != 0) { 2345 if ((flags & TAG_OBJECT) != 0) {
2095 addq(result, Immediate(kHeapObjectTag)); 2346 addq(result, Immediate(kHeapObjectTag));
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2357 CPU::FlushICache(address_, size_); 2608 CPU::FlushICache(address_, size_);
2358 2609
2359 // Check that the code was patched as expected. 2610 // Check that the code was patched as expected.
2360 ASSERT(masm_.pc_ == address_ + size_); 2611 ASSERT(masm_.pc_ == address_ + size_);
2361 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2612 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2362 } 2613 }
2363 2614
2364 } } // namespace v8::internal 2615 } } // namespace v8::internal
2365 2616
2366 #endif // V8_TARGET_ARCH_X64 2617 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698