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

Side by Side Diff: runtime/vm/flow_graph_compiler_ia32.cc

Issue 10500005: More shared code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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
OLDNEW
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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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_stats.h" 11 #include "vm/compiler_stats.h"
12 #include "vm/debugger.h"
13 #include "vm/il_printer.h" 12 #include "vm/il_printer.h"
14 #include "vm/intrinsifier.h"
15 #include "vm/locations.h" 13 #include "vm/locations.h"
16 #include "vm/longjump.h"
17 #include "vm/stub_code.h" 14 #include "vm/stub_code.h"
18 15
19 namespace dart { 16 namespace dart {
20 17
21 DECLARE_FLAG(bool, code_comments); 18 DECLARE_FLAG(bool, code_comments);
22 DECLARE_FLAG(bool, compiler_stats); 19 DECLARE_FLAG(bool, compiler_stats);
23 DECLARE_FLAG(bool, enable_type_checks); 20 DECLARE_FLAG(bool, enable_type_checks);
24 DECLARE_FLAG(bool, intrinsify);
25 DECLARE_FLAG(int, optimization_counter_threshold);
26 DECLARE_FLAG(bool, print_ast); 21 DECLARE_FLAG(bool, print_ast);
27 DECLARE_FLAG(bool, print_scopes); 22 DECLARE_FLAG(bool, print_scopes);
28 DECLARE_FLAG(bool, report_usage_count);
29 DECLARE_FLAG(bool, trace_functions); 23 DECLARE_FLAG(bool, trace_functions);
30 24
31 25
32 void DeoptimizationStub::GenerateCode(FlowGraphCompilerShared* compiler) { 26 void DeoptimizationStub::GenerateCode(FlowGraphCompilerShared* compiler) {
33 Assembler* assem = compiler->assembler(); 27 Assembler* assem = compiler->assembler();
34 #define __ assem-> 28 #define __ assem->
35 __ Comment("Deopt stub for id %d", deopt_id_); 29 __ Comment("Deopt stub for id %d", deopt_id_);
36 __ Bind(entry_label()); 30 __ Bind(entry_label());
37 for (intptr_t i = 0; i < registers_.length(); i++) { 31 for (intptr_t i = 0; i < registers_.length(); i++) {
38 if (registers_[i] != kNoRegister) { 32 if (registers_[i] != kNoRegister) {
(...skipping 14 matching lines...) Expand all
53 Assembler* assembler, 47 Assembler* assembler,
54 const ParsedFunction& parsed_function, 48 const ParsedFunction& parsed_function,
55 const GrowableArray<BlockEntryInstr*>& block_order, 49 const GrowableArray<BlockEntryInstr*>& block_order,
56 bool is_optimizing) 50 bool is_optimizing)
57 : FlowGraphCompilerShared(assembler, 51 : FlowGraphCompilerShared(assembler,
58 parsed_function, 52 parsed_function,
59 block_order, 53 block_order,
60 is_optimizing) {} 54 is_optimizing) {}
61 55
62 56
63 void FlowGraphCompiler::FinalizeComments(const Code& code) {
64 code.set_comments(assembler()->GetCodeComments());
65 }
66
67
68 void FlowGraphCompiler::Bailout(const char* reason) {
69 const char* kFormat = "FlowGraphCompiler Bailout: %s %s.";
70 const char* function_name = parsed_function().function().ToCString();
71 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
72 char* chars = reinterpret_cast<char*>(
73 Isolate::Current()->current_zone()->Allocate(len));
74 OS::SNPrint(chars, len, kFormat, function_name, reason);
75 const Error& error = Error::Handle(
76 LanguageError::New(String::Handle(String::New(chars))));
77 Isolate::Current()->long_jump_base()->Jump(1, error);
78 }
79
80
81 #define __ assembler()-> 57 #define __ assembler()->
82 58
83 void FlowGraphCompiler::IntrinsifyGetter() { 59 void FlowGraphCompiler::IntrinsifyGetter() {
84 // TOS: return address. 60 // TOS: return address.
85 // +1 : receiver. 61 // +1 : receiver.
86 // Sequence node has one return node, its input is load field node. 62 // Sequence node has one return node, its input is load field node.
87 const SequenceNode& sequence_node = *parsed_function().node_sequence(); 63 const SequenceNode& sequence_node = *parsed_function().node_sequence();
88 ASSERT(sequence_node.length() == 1); 64 ASSERT(sequence_node.length() == 1);
89 ASSERT(sequence_node.NodeAt(0)->IsReturnNode()); 65 ASSERT(sequence_node.NodeAt(0)->IsReturnNode());
90 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode(); 66 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode();
(...skipping 20 matching lines...) Expand all
111 __ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver. 87 __ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver.
112 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Value. 88 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Value.
113 __ StoreIntoObject(EAX, FieldAddress(EAX, store_node.field().Offset()), EBX); 89 __ StoreIntoObject(EAX, FieldAddress(EAX, store_node.field().Offset()), EBX);
114 const Immediate raw_null = 90 const Immediate raw_null =
115 Immediate(reinterpret_cast<intptr_t>(Object::null())); 91 Immediate(reinterpret_cast<intptr_t>(Object::null()));
116 __ movl(EAX, raw_null); 92 __ movl(EAX, raw_null);
117 __ ret(); 93 __ ret();
118 } 94 }
119 95
120 96
121 bool FlowGraphCompiler::CanOptimize() {
122 return
123 !FLAG_report_usage_count &&
124 (FLAG_optimization_counter_threshold >= 0) &&
125 !Isolate::Current()->debugger()->IsActive();
126 }
127
128
129 // Returns 'true' if code generation for this function is complete, i.e.,
130 // no fall-through to regular code is needed.
131 bool FlowGraphCompiler::TryIntrinsify() {
132 if (!CanOptimize()) return false;
133 // Intrinsification skips arguments checks, therefore disable if in checked
134 // mode.
135 if (FLAG_intrinsify && !FLAG_trace_functions && !FLAG_enable_type_checks) {
136 if ((parsed_function().function().kind() == RawFunction::kImplicitGetter)) {
137 IntrinsifyGetter();
138 return true;
139 }
140 if ((parsed_function().function().kind() == RawFunction::kImplicitSetter)) {
141 IntrinsifySetter();
142 return true;
143 }
144 }
145 // Even if an intrinsified version of the function was successfully
146 // generated, it may fall through to the non-intrinsified method body.
147 if (!FLAG_trace_functions) {
148 return Intrinsifier::Intrinsify(parsed_function().function(), assembler());
149 }
150 return false;
151 }
152 97
153 98
154 void FlowGraphCompiler::GenerateCallRuntime(intptr_t cid, 99 void FlowGraphCompiler::GenerateCallRuntime(intptr_t cid,
155 intptr_t token_index, 100 intptr_t token_index,
156 intptr_t try_index, 101 intptr_t try_index,
157 const RuntimeEntry& entry) { 102 const RuntimeEntry& entry) {
158 __ CallRuntime(entry); 103 __ CallRuntime(entry);
159 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index); 104 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index);
160 } 105 }
161 106
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 // at entry point. 382 // at entry point.
438 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode, 383 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode,
439 assembler()->CodeSize(), 384 assembler()->CodeSize(),
440 AstNode::kNoId, 385 AstNode::kNoId,
441 0, 386 0,
442 -1); 387 -1);
443 __ jmp(&StubCode::FixCallersTargetLabel()); 388 __ jmp(&StubCode::FixCallersTargetLabel());
444 } 389 }
445 390
446 391
447 void FlowGraphCompiler::EmitInstanceCall(intptr_t cid, 392 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
448 intptr_t token_index, 393 const ICData& ic_data,
449 intptr_t try_index, 394 const Array& arguments_descriptor,
450 const String& function_name, 395 intptr_t argument_count) {
451 intptr_t argument_count,
452 const Array& argument_names,
453 intptr_t checked_argument_count) {
454 ICData& ic_data = ICData::ZoneHandle(ICData::New(parsed_function().function(),
455 function_name,
456 cid,
457 checked_argument_count));
458 const Array& arguments_descriptor =
459 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names);
460 __ LoadObject(ECX, ic_data); 396 __ LoadObject(ECX, ic_data);
461 __ LoadObject(EDX, arguments_descriptor); 397 __ LoadObject(EDX, arguments_descriptor);
462 398
463 uword label_address = 0; 399 __ call(target_label);
464 switch (checked_argument_count) { 400 const intptr_t descr_offset = assembler()->CodeSize();
465 case 1:
466 label_address = StubCode::OneArgCheckInlineCacheEntryPoint();
467 break;
468 case 2:
469 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint();
470 break;
471 default:
472 UNIMPLEMENTED();
473 }
474 ExternalLabel target_label("InlineCache", label_address);
475 __ call(&target_label);
476 AddCurrentDescriptor(PcDescriptors::kIcCall, cid, token_index, try_index);
477 __ Drop(argument_count); 401 __ Drop(argument_count);
402 return descr_offset;
478 } 403 }
479 404
480 405
481 void FlowGraphCompiler::EmitStaticCall(intptr_t token_index, 406 intptr_t FlowGraphCompiler::EmitStaticCall(const Function& function,
482 intptr_t try_index, 407 const Array& arguments_descriptor,
483 const Function& function, 408 intptr_t argument_count) {
484 intptr_t argument_count,
485 const Array& argument_names) {
486 const Array& arguments_descriptor =
487 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names);
488 __ LoadObject(ECX, function); 409 __ LoadObject(ECX, function);
489 __ LoadObject(EDX, arguments_descriptor); 410 __ LoadObject(EDX, arguments_descriptor);
490 411 __ call(&StubCode::CallStaticFunctionLabel());
491 GenerateCall(token_index, 412 const intptr_t descr_offset = assembler()->CodeSize();
492 try_index,
493 &StubCode::CallStaticFunctionLabel(),
494 PcDescriptors::kFuncCall);
495 __ Drop(argument_count); 413 __ Drop(argument_count);
414 return descr_offset;
496 } 415 }
497 416
498 417
499 void FlowGraphCompiler::GenerateCall(intptr_t token_index, 418 void FlowGraphCompiler::GenerateCall(intptr_t token_index,
500 intptr_t try_index, 419 intptr_t try_index,
501 const ExternalLabel* label, 420 const ExternalLabel* label,
502 PcDescriptors::Kind kind) { 421 PcDescriptors::Kind kind) {
503 __ call(label); 422 __ call(label);
504 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index); 423 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index);
505 } 424 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 } 484 }
566 } 485 }
567 } 486 }
568 } 487 }
569 488
570 #undef __ 489 #undef __
571 490
572 } // namespace dart 491 } // namespace dart
573 492
574 #endif // defined TARGET_ARCH_IA32 493 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698