Chromium Code Reviews| 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" |
| 11 #include "vm/code_generator.h" | 11 #include "vm/code_generator.h" |
| 12 #include "vm/disassembler.h" | 12 #include "vm/disassembler.h" |
| 13 #include "vm/longjump.h" | 13 #include "vm/longjump.h" |
| 14 #include "vm/parser.h" | 14 #include "vm/parser.h" |
| 15 #include "vm/stub_code.h" | 15 #include "vm/stub_code.h" |
| 16 | 16 |
| 17 namespace dart { | 17 namespace dart { |
| 18 | 18 |
| 19 DECLARE_FLAG(bool, enable_type_checks); | |
| 19 DECLARE_FLAG(bool, print_ast); | 20 DECLARE_FLAG(bool, print_ast); |
| 20 DECLARE_FLAG(bool, print_scopes); | 21 DECLARE_FLAG(bool, print_scopes); |
| 21 DECLARE_FLAG(bool, trace_functions); | 22 DECLARE_FLAG(bool, trace_functions); |
| 22 | 23 |
| 23 void FlowGraphCompiler::Bailout(const char* reason) { | 24 void FlowGraphCompiler::Bailout(const char* reason) { |
| 24 const char* kFormat = "FlowGraphCompiler Bailout: %s %s."; | 25 const char* kFormat = "FlowGraphCompiler Bailout: %s %s."; |
| 25 const char* function_name = parsed_function_.function().ToCString(); | 26 const char* function_name = parsed_function_.function().ToCString(); |
| 26 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 27 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 27 char* chars = reinterpret_cast<char*>( | 28 char* chars = reinterpret_cast<char*>( |
| 28 Isolate::Current()->current_zone()->Allocate(len)); | 29 Isolate::Current()->current_zone()->Allocate(len)); |
| 29 OS::SNPrint(chars, len, kFormat, function_name, reason); | 30 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 30 const Error& error = Error::Handle( | 31 const Error& error = Error::Handle( |
| 31 LanguageError::New(String::Handle(String::New(chars)))); | 32 LanguageError::New(String::Handle(String::New(chars)))); |
| 32 Isolate::Current()->long_jump_base()->Jump(1, error); | 33 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 33 } | 34 } |
| 34 | 35 |
| 36 #define __ assembler_-> | |
| 35 | 37 |
| 36 #define __ assembler_-> | 38 |
| 39 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t node_id, | |
| 40 intptr_t token_index, | |
| 41 const AbstractType& dst_type, | |
| 42 const String& dst_name) { | |
| 43 Bailout("GenerateAssertAssignable"); | |
| 44 } | |
| 45 | |
| 37 | 46 |
| 38 void FlowGraphCompiler::LoadValue(Value* value) { | 47 void FlowGraphCompiler::LoadValue(Value* value) { |
| 39 if (value->IsConstant()) { | 48 if (value->IsConstant()) { |
| 40 ConstantVal* constant = value->AsConstant(); | 49 ConstantVal* constant = value->AsConstant(); |
| 41 if (constant->instance().IsSmi()) { | 50 if (constant->instance().IsSmi()) { |
| 42 int64_t imm = reinterpret_cast<int64_t>(constant->instance().raw()); | 51 int64_t imm = reinterpret_cast<int64_t>(constant->instance().raw()); |
| 43 __ movq(RAX, Immediate(imm)); | 52 __ movq(RAX, Immediate(imm)); |
| 44 } else { | 53 } else { |
| 45 __ LoadObject(RAX, value->AsConstant()->instance()); | 54 __ LoadObject(RAX, value->AsConstant()->instance()); |
| 46 } | 55 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 169 LoadValue(comp->value()); | 178 LoadValue(comp->value()); |
| 170 __ movq(Address(RBP, comp->local().index() * kWordSize), RAX); | 179 __ movq(Address(RBP, comp->local().index() * kWordSize), RAX); |
| 171 } | 180 } |
| 172 | 181 |
| 173 | 182 |
| 174 void FlowGraphCompiler::VisitNativeCall(NativeCallComp* comp) { | 183 void FlowGraphCompiler::VisitNativeCall(NativeCallComp* comp) { |
| 175 Bailout("NativeCallComp"); | 184 Bailout("NativeCallComp"); |
| 176 } | 185 } |
| 177 | 186 |
| 178 | 187 |
| 188 void FlowGraphCompiler::VisitLoadInstanceField(LoadInstanceFieldComp* comp) { | |
| 189 LoadValue(comp->instance()); // -> RAX. | |
| 190 __ movq(RAX, FieldAddress(RAX, comp->field_offset())); | |
| 191 } | |
| 192 | |
| 193 | |
| 194 void FlowGraphCompiler::VisitStoreInstanceField(StoreInstanceFieldComp* comp) { | |
| 195 LoadValue(comp->value()); | |
| 196 if (FLAG_enable_type_checks) { | |
| 197 GenerateAssertAssignable(comp->node_id(), | |
|
Kevin Millikin (Google)
2012/03/05 11:02:41
There is an AssertAssignableComp that can go in th
srdjan
2012/03/05 18:35:21
Moved to graph builder.
| |
| 198 comp->token_index(), | |
| 199 AbstractType::ZoneHandle(comp->field_type()), | |
| 200 String::ZoneHandle(comp->field_name())); | |
| 201 } | |
| 202 __ movq(R10, RAX); | |
| 203 LoadValue(comp->instance()); // -> RAX. | |
| 204 __ StoreIntoObject(RAX, FieldAddress(RAX, comp->field_offset()), R10); | |
| 205 } | |
| 206 | |
| 207 | |
| 208 | |
| 209 void FlowGraphCompiler::VisitLoadStaticField(LoadStaticFieldComp* comp) { | |
| 210 __ LoadObject(RDX, comp->field()); | |
| 211 __ movq(RAX, FieldAddress(RDX, Field::value_offset())); | |
| 212 } | |
| 213 | |
| 214 | |
| 215 void FlowGraphCompiler::VisitStoreStaticField(StoreStaticFieldComp* comp) { | |
| 216 LoadValue(comp->value()); | |
| 217 if (FLAG_enable_type_checks) { | |
|
srdjan
2012/03/05 18:35:21
Removed here as well.
| |
| 218 GenerateAssertAssignable(comp->node_id(), | |
| 219 comp->token_index(), | |
| 220 AbstractType::ZoneHandle(comp->field().type()), | |
| 221 String::ZoneHandle(comp->field().name())); | |
| 222 } | |
| 223 __ LoadObject(RDX, comp->field()); | |
| 224 __ StoreIntoObject(RDX, FieldAddress(RDX, Field::value_offset()), RAX); | |
| 225 } | |
| 226 | |
| 227 | |
| 179 void FlowGraphCompiler::VisitStoreIndexed(StoreIndexedComp* comp) { | 228 void FlowGraphCompiler::VisitStoreIndexed(StoreIndexedComp* comp) { |
| 180 // Call operator []= but preserve the third argument value under the | 229 // Call operator []= but preserve the third argument value under the |
| 181 // arguments as the result of the computation. | 230 // arguments as the result of the computation. |
| 182 const String& function_name = | 231 const String& function_name = |
| 183 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 232 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
| 184 // Placeholder is under value, index, and receiver. | 233 // Placeholder is under value, index, and receiver. |
| 185 const int kPlaceholderOffset = 3 * kWordSize; | 234 const int kPlaceholderOffset = 3 * kWordSize; |
| 186 __ movq(RAX, Address(RSP, 0)); // Value. | 235 __ movq(RAX, Address(RSP, 0)); // Value. |
| 187 __ movq(Address(RSP, kPlaceholderOffset), RAX); | 236 __ movq(Address(RSP, kPlaceholderOffset), RAX); |
| 188 EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 3, | 237 EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 3, |
| 189 Array::ZoneHandle(), 1); | 238 Array::ZoneHandle(), 1); |
| 190 __ popq(RAX); | 239 __ popq(RAX); |
| 191 } | 240 } |
| 192 | 241 |
| 193 | |
| 194 void FlowGraphCompiler::VisitInstanceSetter(InstanceSetterComp* comp) { | 242 void FlowGraphCompiler::VisitInstanceSetter(InstanceSetterComp* comp) { |
| 195 // Preserve the second argument under the arguments as the result of the | 243 // Preserve the second argument under the arguments as the result of the |
| 196 // computation, then call the getter. | 244 // computation, then call the getter. |
| 197 const String& function_name = | 245 const String& function_name = |
| 198 String::ZoneHandle(Field::SetterSymbol(comp->field_name())); | 246 String::ZoneHandle(Field::SetterSymbol(comp->field_name())); |
| 199 // Placeholder is under value and receiver. | 247 // Placeholder is under value and receiver. |
| 200 const int kPlaceholderOffset = 2 * kWordSize; | 248 const int kPlaceholderOffset = 2 * kWordSize; |
| 201 __ movq(RAX, Address(RSP, 0)); // Value. | 249 __ movq(RAX, Address(RSP, 0)); // Value. |
| 202 __ movq(Address(RSP, kPlaceholderOffset), RAX); | 250 __ movq(Address(RSP, kPlaceholderOffset), RAX); |
| 203 EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 2, | 251 EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 2, |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { | 460 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { |
| 413 // We don't compile exception handlers yet. | 461 // We don't compile exception handlers yet. |
| 414 code.set_exception_handlers( | 462 code.set_exception_handlers( |
| 415 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); | 463 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); |
| 416 } | 464 } |
| 417 | 465 |
| 418 | 466 |
| 419 } // namespace dart | 467 } // namespace dart |
| 420 | 468 |
| 421 #endif // defined TARGET_ARCH_X64 | 469 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |