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 "vm/ast_printer.h" | 10 #include "vm/ast_printer.h" |
| 11 #include "vm/compiler.h" |
11 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
12 #include "vm/deopt_instructions.h" | 13 #include "vm/deopt_instructions.h" |
13 #include "vm/il_printer.h" | 14 #include "vm/il_printer.h" |
14 #include "vm/locations.h" | 15 #include "vm/locations.h" |
15 #include "vm/object_store.h" | 16 #include "vm/object_store.h" |
16 #include "vm/parser.h" | 17 #include "vm/parser.h" |
17 #include "vm/stack_frame.h" | 18 #include "vm/stack_frame.h" |
18 #include "vm/stub_code.h" | 19 #include "vm/stub_code.h" |
19 #include "vm/symbols.h" | 20 #include "vm/symbols.h" |
20 | 21 |
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 if (flow_graph().IsCompiledForOsr()) { | 1125 if (flow_graph().IsCompiledForOsr()) { |
1125 intptr_t extra_slots = StackSize() | 1126 intptr_t extra_slots = StackSize() |
1126 - flow_graph().num_stack_locals() | 1127 - flow_graph().num_stack_locals() |
1127 - flow_graph().num_copied_params(); | 1128 - flow_graph().num_copied_params(); |
1128 ASSERT(extra_slots >= 0); | 1129 ASSERT(extra_slots >= 0); |
1129 __ EnterOsrFrame(extra_slots * kWordSize, new_pp, new_pc); | 1130 __ EnterOsrFrame(extra_slots * kWordSize, new_pp, new_pc); |
1130 } else { | 1131 } else { |
1131 ASSERT(StackSize() >= 0); | 1132 ASSERT(StackSize() >= 0); |
1132 __ EnterDartFrameWithInfo(StackSize() * kWordSize, new_pp, new_pc); | 1133 __ EnterDartFrameWithInfo(StackSize() * kWordSize, new_pp, new_pc); |
1133 } | 1134 } |
| 1135 |
| 1136 // TODO(zra): maybe do this only before we try to optimize? |
| 1137 if (FLAG_collect_code) { |
| 1138 // If we are collecting code, make sure this function still has a pointer |
| 1139 // to the code object. |
| 1140 // TODO(zra): Is it cheaper just to write the Function fields with the |
| 1141 // code object without doing the test? |
| 1142 Label is_connected; |
| 1143 const Register function_reg = RDI; |
| 1144 __ LoadObject(function_reg, function, PP); |
| 1145 __ movq(RAX, FieldAddress(function_reg, Function::code_offset())); |
| 1146 __ CompareObject(RAX, Object::null_object(), PP); |
| 1147 __ j(NOT_EQUAL, &is_connected, Assembler::kNearJump); |
| 1148 __ movq(RAX, Address(RBP, kPcMarkerSlotFromFp * kWordSize)); |
| 1149 const intptr_t code_pc_dist = |
| 1150 Instructions::HeaderSize() - Instructions::code_offset() + |
| 1151 Assembler::kEntryPointToPcMarkerOffset; |
| 1152 __ movq(RAX, Address(RAX, -code_pc_dist)); |
| 1153 __ movq(FieldAddress(function_reg, Function::code_offset()), RAX); |
| 1154 __ movl( |
| 1155 FieldAddress(function_reg, Function::unoptimized_code_offset()), RAX); |
| 1156 __ Bind(&is_connected); |
| 1157 } |
1134 } | 1158 } |
1135 | 1159 |
1136 | 1160 |
1137 void FlowGraphCompiler::CompileGraph() { | 1161 void FlowGraphCompiler::CompileGraph() { |
1138 InitCompiler(); | 1162 InitCompiler(); |
1139 | 1163 |
1140 TryIntrinsify(); | 1164 TryIntrinsify(); |
1141 | 1165 |
1142 EmitFrameEntry(); | 1166 EmitFrameEntry(); |
1143 | 1167 |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1440 __ j(ZERO, &call_target_function, Assembler::kNearJump); | 1464 __ j(ZERO, &call_target_function, Assembler::kNearJump); |
1441 __ cmpq(RDX, RAX); | 1465 __ cmpq(RDX, RAX); |
1442 __ j(NOT_EQUAL, &update, Assembler::kNearJump); | 1466 __ j(NOT_EQUAL, &update, Assembler::kNearJump); |
1443 | 1467 |
1444 __ Bind(&call_target_function); | 1468 __ Bind(&call_target_function); |
1445 // Call the target found in the cache. For a class id match, this is a | 1469 // Call the target found in the cache. For a class id match, this is a |
1446 // proper target for the given name and arguments descriptor. If the | 1470 // proper target for the given name and arguments descriptor. If the |
1447 // illegal class id was found, the target is a cache miss handler that can | 1471 // illegal class id was found, the target is a cache miss handler that can |
1448 // be invoked as a normal Dart function. | 1472 // be invoked as a normal Dart function. |
1449 __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize)); | 1473 __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize)); |
1450 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); | 1474 __ movq(RBX, FieldAddress(RAX, Function::code_offset())); |
1451 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 1475 if (FLAG_collect_code) { |
| 1476 // If we are collecting code, the code object may be null. |
| 1477 Label is_compiled; |
| 1478 const Immediate& raw_null = |
| 1479 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1480 __ cmpq(RBX, raw_null); |
| 1481 __ j(NOT_EQUAL, &is_compiled, Assembler::kNearJump); |
| 1482 __ EnterStubFrame(); |
| 1483 __ pushq(RDX); // Preserve arguments descriptor array. |
| 1484 __ pushq(RCX); // Preserve IC data object. |
| 1485 __ pushq(RAX); // Pass function. |
| 1486 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1487 __ popq(RAX); // Restore function. |
| 1488 __ popq(RCX); // Restore IC data array. |
| 1489 __ popq(RDX); // Restore arguments descriptor array. |
| 1490 __ LeaveFrame(); |
| 1491 __ movq(RBX, FieldAddress(RAX, Function::code_offset())); |
| 1492 __ Bind(&is_compiled); |
| 1493 } |
| 1494 __ movq(RAX, FieldAddress(RBX, Code::instructions_offset())); |
1452 __ LoadObject(RBX, ic_data, PP); | 1495 __ LoadObject(RBX, ic_data, PP); |
1453 __ LoadObject(R10, arguments_descriptor, PP); | 1496 __ LoadObject(R10, arguments_descriptor, PP); |
1454 __ AddImmediate( | 1497 __ AddImmediate( |
1455 RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag), PP); | 1498 RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag), PP); |
1456 __ call(RAX); | 1499 __ call(RAX); |
1457 AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos); | 1500 AddCurrentDescriptor(PcDescriptors::kOther, Isolate::kNoDeoptId, token_pos); |
1458 RecordSafepoint(locs); | 1501 RecordSafepoint(locs); |
1459 AddDeoptIndexAtCall(Isolate::ToDeoptAfter(deopt_id), token_pos); | 1502 AddDeoptIndexAtCall(Isolate::ToDeoptAfter(deopt_id), token_pos); |
1460 __ Drop(argument_count); | 1503 __ Drop(argument_count); |
1461 } | 1504 } |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1934 __ movups(reg, Address(RSP, 0)); | 1977 __ movups(reg, Address(RSP, 0)); |
1935 __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP); | 1978 __ AddImmediate(RSP, Immediate(kFpuRegisterSize), PP); |
1936 } | 1979 } |
1937 | 1980 |
1938 | 1981 |
1939 #undef __ | 1982 #undef __ |
1940 | 1983 |
1941 } // namespace dart | 1984 } // namespace dart |
1942 | 1985 |
1943 #endif // defined TARGET_ARCH_X64 | 1986 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |