| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 __ LoadObject(RAX, value->AsConstant()->instance()); | 45 __ LoadObject(RAX, value->AsConstant()->instance()); |
| 46 } | 46 } |
| 47 } else { | 47 } else { |
| 48 ASSERT(value->IsTemp()); | 48 ASSERT(value->IsTemp()); |
| 49 __ popq(RAX); | 49 __ popq(RAX); |
| 50 } | 50 } |
| 51 } | 51 } |
| 52 | 52 |
| 53 | 53 |
| 54 void FlowGraphCompiler::VisitTemp(TempVal* val) { | 54 void FlowGraphCompiler::VisitTemp(TempVal* val) { |
| 55 Bailout("TempVal"); | 55 LoadValue(val); |
| 56 } | 56 } |
| 57 | 57 |
| 58 | 58 |
| 59 void FlowGraphCompiler::VisitConstant(ConstantVal* val) { | 59 void FlowGraphCompiler::VisitConstant(ConstantVal* val) { |
| 60 Bailout("ConstantVal"); | 60 LoadValue(val); |
| 61 } | 61 } |
| 62 | 62 |
| 63 | 63 |
| 64 void FlowGraphCompiler::VisitAssertAssignable(AssertAssignableComp* comp) { | 64 void FlowGraphCompiler::VisitAssertAssignable(AssertAssignableComp* comp) { |
| 65 Bailout("AssertAssignableComp"); | 65 Bailout("AssertAssignableComp"); |
| 66 } | 66 } |
| 67 | 67 |
| 68 | 68 |
| 69 // True iff. the arguments to a call will be properly pushed and can |
| 70 // be popped after the call. |
| 71 template <typename T> static bool VerifyCallComputation(T* comp) { |
| 72 // Argument values should be consecutive temps. |
| 73 // |
| 74 // TODO(kmillikin): implement stack height tracking so we can also assert |
| 75 // they are on top of the stack. |
| 76 intptr_t previous = -1; |
| 77 for (int i = 0; i < comp->ArgumentCount(); ++i) { |
| 78 TempVal* temp = comp->ArgumentAt(i)->AsTemp(); |
| 79 if (temp == NULL) return false; |
| 80 if (i != 0) { |
| 81 if (temp->index() != previous + 1) return false; |
| 82 } |
| 83 previous = temp->index(); |
| 84 } |
| 85 return true; |
| 86 } |
| 87 |
| 88 |
| 69 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) { | 89 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) { |
| 70 Bailout("InstanceCallComp"); | 90 ASSERT(VerifyCallComputation(comp)); |
| 91 |
| 92 ICData& ic_data = |
| 93 ICData::ZoneHandle(ICData::New(parsed_function_.function(), |
| 94 comp->function_name(), |
| 95 comp->node_id(), |
| 96 comp->checked_argument_count())); |
| 97 int argument_count = comp->ArgumentCount(); |
| 98 const Array& arguments_descriptor = |
| 99 CodeGenerator::ArgumentsDescriptor(argument_count, |
| 100 comp->argument_names()); |
| 101 __ LoadObject(RBX, ic_data); |
| 102 __ LoadObject(R10, arguments_descriptor); |
| 103 |
| 104 uword label_address = 0; |
| 105 switch (comp->checked_argument_count()) { |
| 106 case 1: |
| 107 label_address = StubCode::OneArgCheckInlineCacheEntryPoint(); |
| 108 break; |
| 109 case 2: |
| 110 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint(); |
| 111 break; |
| 112 default: |
| 113 UNIMPLEMENTED(); |
| 114 } |
| 115 ExternalLabel target_label("InlineCache", label_address); |
| 116 __ call(&target_label); |
| 117 AddCurrentDescriptor(PcDescriptors::kIcCall, |
| 118 comp->node_id(), |
| 119 comp->token_index()); |
| 120 __ addq(RSP, Immediate(argument_count * kWordSize)); |
| 71 } | 121 } |
| 72 | 122 |
| 73 | 123 |
| 74 void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) { | 124 void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) { |
| 75 Bailout("StrictCompareComp"); | 125 Bailout("StrictCompareComp"); |
| 76 } | 126 } |
| 77 | 127 |
| 78 | 128 |
| 79 | 129 |
| 80 void FlowGraphCompiler::VisitStaticCall(StaticCallComp* comp) { | 130 void FlowGraphCompiler::VisitStaticCall(StaticCallComp* comp) { |
| 81 Bailout("StaticCallComp"); | 131 ASSERT(VerifyCallComputation(comp)); |
| 132 |
| 133 int argument_count = comp->ArgumentCount(); |
| 134 const Array& arguments_descriptor = |
| 135 CodeGenerator::ArgumentsDescriptor(argument_count, |
| 136 comp->argument_names()); |
| 137 __ LoadObject(RBX, comp->function()); |
| 138 __ LoadObject(R10, arguments_descriptor); |
| 139 |
| 140 GenerateCall(comp->token_index(), |
| 141 &StubCode::CallStaticFunctionLabel(), |
| 142 PcDescriptors::kFuncCall); |
| 143 __ addq(RSP, Immediate(argument_count * kWordSize)); |
| 82 } | 144 } |
| 83 | 145 |
| 84 | 146 |
| 85 void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) { | 147 void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) { |
| 86 if (comp->local().is_captured()) { | 148 if (comp->local().is_captured()) { |
| 87 Bailout("load of context variable"); | 149 Bailout("load of context variable"); |
| 88 } | 150 } |
| 89 __ movq(RAX, Address(RBP, comp->local().index() * kWordSize)); | 151 __ movq(RAX, Address(RBP, comp->local().index() * kWordSize)); |
| 90 } | 152 } |
| 91 | 153 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode, | 313 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode, |
| 252 assembler_->CodeSize(), | 314 assembler_->CodeSize(), |
| 253 AstNode::kNoId, | 315 AstNode::kNoId, |
| 254 0, | 316 0, |
| 255 -1); | 317 -1); |
| 256 __ jmp(&StubCode::FixCallersTargetLabel()); | 318 __ jmp(&StubCode::FixCallersTargetLabel()); |
| 257 } | 319 } |
| 258 | 320 |
| 259 | 321 |
| 260 // Infrastructure copied from class CodeGenerator. | 322 // Infrastructure copied from class CodeGenerator. |
| 323 void FlowGraphCompiler::GenerateCall(intptr_t token_index, |
| 324 const ExternalLabel* label, |
| 325 PcDescriptors::Kind kind) { |
| 326 __ call(label); |
| 327 AddCurrentDescriptor(kind, AstNode::kNoId, token_index); |
| 328 } |
| 329 |
| 330 |
| 261 void FlowGraphCompiler::GenerateCallRuntime(intptr_t node_id, | 331 void FlowGraphCompiler::GenerateCallRuntime(intptr_t node_id, |
| 262 intptr_t token_index, | 332 intptr_t token_index, |
| 263 const RuntimeEntry& entry) { | 333 const RuntimeEntry& entry) { |
| 264 __ CallRuntimeFromDart(entry); | 334 __ CallRuntimeFromDart(entry); |
| 265 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index); | 335 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index); |
| 266 } | 336 } |
| 267 | 337 |
| 268 | 338 |
| 269 // Uses current pc position and try-index. | 339 // Uses current pc position and try-index. |
| 270 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, | 340 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 297 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { | 367 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { |
| 298 // We don't compile exception handlers yet. | 368 // We don't compile exception handlers yet. |
| 299 code.set_exception_handlers( | 369 code.set_exception_handlers( |
| 300 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); | 370 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); |
| 301 } | 371 } |
| 302 | 372 |
| 303 | 373 |
| 304 } // namespace dart | 374 } // namespace dart |
| 305 | 375 |
| 306 #endif // defined TARGET_ARCH_X64 | 376 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |