| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1421 __ LoadObject(R10, arguments_descriptor); | 1421 __ LoadObject(R10, arguments_descriptor); |
| 1422 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1422 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1423 __ call(RAX); | 1423 __ call(RAX); |
| 1424 AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos); | 1424 AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos); |
| 1425 RecordSafepoint(locs); | 1425 RecordSafepoint(locs); |
| 1426 AddDeoptIndexAtCall(Isolate::ToDeoptAfter(deopt_id), token_pos); | 1426 AddDeoptIndexAtCall(Isolate::ToDeoptAfter(deopt_id), token_pos); |
| 1427 __ Drop(argument_count); | 1427 __ Drop(argument_count); |
| 1428 } | 1428 } |
| 1429 | 1429 |
| 1430 | 1430 |
| 1431 void FlowGraphCompiler::EmitStaticCall(const Function& function, | 1431 void FlowGraphCompiler::EmitOptimizedStaticCall( |
| 1432 const Array& arguments_descriptor, | 1432 const Function& function, |
| 1433 intptr_t argument_count, | 1433 const Array& arguments_descriptor, |
| 1434 intptr_t deopt_id, | 1434 intptr_t argument_count, |
| 1435 intptr_t token_pos, | 1435 intptr_t deopt_id, |
| 1436 LocationSummary* locs) { | 1436 intptr_t token_pos, |
| 1437 LocationSummary* locs) { |
| 1437 __ LoadObject(R10, arguments_descriptor); | 1438 __ LoadObject(R10, arguments_descriptor); |
| 1438 // Do not use the code from the function, but let the code be patched so that | 1439 // Do not use the code from the function, but let the code be patched so that |
| 1439 // we can record the outgoing edges to other code. | 1440 // we can record the outgoing edges to other code. |
| 1440 GenerateDartCall(deopt_id, | 1441 GenerateDartCall(deopt_id, |
| 1441 token_pos, | 1442 token_pos, |
| 1442 &StubCode::CallStaticFunctionLabel(), | 1443 &StubCode::CallStaticFunctionLabel(), |
| 1443 PcDescriptors::kFuncCall, | 1444 PcDescriptors::kOptStaticCall, |
| 1444 locs); | 1445 locs); |
| 1445 AddStaticCallTarget(function); | 1446 AddStaticCallTarget(function); |
| 1446 __ Drop(argument_count); | 1447 __ Drop(argument_count); |
| 1447 } | 1448 } |
| 1448 | 1449 |
| 1449 | 1450 |
| 1450 void FlowGraphCompiler::EmitUnoptimizedStaticCall( | 1451 void FlowGraphCompiler::EmitUnoptimizedStaticCall( |
| 1451 const Function& target_function, | 1452 const Function& target_function, |
| 1452 const Array& arguments_descriptor, | 1453 const Array& arguments_descriptor, |
| 1453 intptr_t argument_count, | 1454 intptr_t argument_count, |
| 1454 intptr_t deopt_id, | 1455 intptr_t deopt_id, |
| 1455 intptr_t token_pos, | 1456 intptr_t token_pos, |
| 1456 LocationSummary* locs) { | 1457 LocationSummary* locs) { |
| 1457 const ICData& ic_data = ICData::ZoneHandle( | 1458 const ICData& ic_data = ICData::ZoneHandle( |
| 1458 ICData::New(parsed_function().function(), // Caller function. | 1459 ICData::New(parsed_function().function(), // Caller function. |
| 1459 String::Handle(target_function.name()), | 1460 String::Handle(target_function.name()), |
| 1460 arguments_descriptor, | 1461 arguments_descriptor, |
| 1461 deopt_id, | 1462 deopt_id, |
| 1462 0)); // No arguments checked. | 1463 0)); // No arguments checked. |
| 1463 ic_data.AddTarget(target_function); | 1464 ic_data.AddTarget(target_function); |
| 1464 __ LoadObject(RBX, ic_data); | 1465 __ LoadObject(RBX, ic_data); |
| 1465 GenerateDartCall(deopt_id, | 1466 GenerateDartCall(deopt_id, |
| 1466 token_pos, | 1467 token_pos, |
| 1467 &StubCode::UnoptimizedStaticCallLabel(), | 1468 &StubCode::UnoptimizedStaticCallLabel(), |
| 1468 PcDescriptors::kFuncCall, | 1469 PcDescriptors::kUnoptStaticCall, |
| 1469 locs); | 1470 locs); |
| 1470 __ Drop(argument_count); | 1471 __ Drop(argument_count); |
| 1471 } | 1472 } |
| 1472 | 1473 |
| 1473 | 1474 |
| 1474 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg, | 1475 void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg, |
| 1475 const Object& obj, | 1476 const Object& obj, |
| 1476 bool needs_number_check, | 1477 bool needs_number_check, |
| 1477 intptr_t token_pos) { | 1478 intptr_t token_pos) { |
| 1478 if (needs_number_check) { | 1479 if (needs_number_check) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1609 | 1610 |
| 1610 | 1611 |
| 1611 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, | 1612 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, |
| 1612 Register class_id_reg, | 1613 Register class_id_reg, |
| 1613 intptr_t argument_count, | 1614 intptr_t argument_count, |
| 1614 const Array& argument_names, | 1615 const Array& argument_names, |
| 1615 Label* deopt, | 1616 Label* deopt, |
| 1616 intptr_t deopt_id, | 1617 intptr_t deopt_id, |
| 1617 intptr_t token_index, | 1618 intptr_t token_index, |
| 1618 LocationSummary* locs) { | 1619 LocationSummary* locs) { |
| 1620 ASSERT(is_optimizing()); |
| 1619 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); | 1621 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); |
| 1620 Label match_found; | 1622 Label match_found; |
| 1621 const intptr_t len = ic_data.NumberOfChecks(); | 1623 const intptr_t len = ic_data.NumberOfChecks(); |
| 1622 GrowableArray<CidTarget> sorted(len); | 1624 GrowableArray<CidTarget> sorted(len); |
| 1623 SortICDataByCount(ic_data, &sorted); | 1625 SortICDataByCount(ic_data, &sorted); |
| 1624 ASSERT(class_id_reg != R10); | 1626 ASSERT(class_id_reg != R10); |
| 1625 ASSERT(len > 0); // Why bother otherwise. | 1627 ASSERT(len > 0); // Why bother otherwise. |
| 1626 const Array& arguments_descriptor = | 1628 const Array& arguments_descriptor = |
| 1627 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, | 1629 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, |
| 1628 argument_names)); | 1630 argument_names)); |
| 1629 __ LoadObject(R10, arguments_descriptor); | 1631 __ LoadObject(R10, arguments_descriptor); |
| 1630 for (intptr_t i = 0; i < len; i++) { | 1632 for (intptr_t i = 0; i < len; i++) { |
| 1631 const bool is_last_check = (i == (len - 1)); | 1633 const bool is_last_check = (i == (len - 1)); |
| 1632 Label next_test; | 1634 Label next_test; |
| 1633 assembler()->cmpl(class_id_reg, Immediate(sorted[i].cid)); | 1635 assembler()->cmpl(class_id_reg, Immediate(sorted[i].cid)); |
| 1634 if (is_last_check) { | 1636 if (is_last_check) { |
| 1635 assembler()->j(NOT_EQUAL, deopt); | 1637 assembler()->j(NOT_EQUAL, deopt); |
| 1636 } else { | 1638 } else { |
| 1637 assembler()->j(NOT_EQUAL, &next_test); | 1639 assembler()->j(NOT_EQUAL, &next_test); |
| 1638 } | 1640 } |
| 1639 // Do not use the code from the function, but let the code be patched so | 1641 // Do not use the code from the function, but let the code be patched so |
| 1640 // that we can record the outgoing edges to other code. | 1642 // that we can record the outgoing edges to other code. |
| 1641 GenerateDartCall(deopt_id, | 1643 GenerateDartCall(deopt_id, |
| 1642 token_index, | 1644 token_index, |
| 1643 &StubCode::CallStaticFunctionLabel(), | 1645 &StubCode::CallStaticFunctionLabel(), |
| 1644 PcDescriptors::kFuncCall, | 1646 PcDescriptors::kOptStaticCall, |
| 1645 locs); | 1647 locs); |
| 1646 const Function& function = *sorted[i].target; | 1648 const Function& function = *sorted[i].target; |
| 1647 AddStaticCallTarget(function); | 1649 AddStaticCallTarget(function); |
| 1648 __ Drop(argument_count); | 1650 __ Drop(argument_count); |
| 1649 if (!is_last_check) { | 1651 if (!is_last_check) { |
| 1650 assembler()->jmp(&match_found); | 1652 assembler()->jmp(&match_found); |
| 1651 } | 1653 } |
| 1652 assembler()->Bind(&next_test); | 1654 assembler()->Bind(&next_test); |
| 1653 } | 1655 } |
| 1654 assembler()->Bind(&match_found); | 1656 assembler()->Bind(&match_found); |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1933 __ movups(reg, Address(RSP, 0)); | 1935 __ movups(reg, Address(RSP, 0)); |
| 1934 __ addq(RSP, Immediate(kFpuRegisterSize)); | 1936 __ addq(RSP, Immediate(kFpuRegisterSize)); |
| 1935 } | 1937 } |
| 1936 | 1938 |
| 1937 | 1939 |
| 1938 #undef __ | 1940 #undef __ |
| 1939 | 1941 |
| 1940 } // namespace dart | 1942 } // namespace dart |
| 1941 | 1943 |
| 1942 #endif // defined TARGET_ARCH_X64 | 1944 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |