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

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
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.h ('k') | runtime/vm/flow_graph_compiler_shared.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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::GenerateInlinedGetter(intptr_t offset) {
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();
88 ASSERT(sequence_node.length() == 1);
89 ASSERT(sequence_node.NodeAt(0)->IsReturnNode());
90 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode();
91 ASSERT(return_node.value()->IsLoadInstanceFieldNode());
92 const LoadInstanceFieldNode& load_node =
93 *return_node.value()->AsLoadInstanceFieldNode();
94 __ movl(EAX, Address(ESP, 1 * kWordSize)); 63 __ movl(EAX, Address(ESP, 1 * kWordSize));
95 __ movl(EAX, FieldAddress(EAX, load_node.field().Offset())); 64 __ movl(EAX, FieldAddress(EAX, offset));
96 __ ret(); 65 __ ret();
97 } 66 }
98 67
99 68
100 void FlowGraphCompiler::IntrinsifySetter() { 69 void FlowGraphCompiler::GenerateInlinedSetter(intptr_t offset) {
101 // TOS: return address. 70 // TOS: return address.
102 // +1 : value 71 // +1 : value
103 // +2 : receiver. 72 // +2 : receiver.
104 // Sequence node has one store node and one return NULL node.
105 const SequenceNode& sequence_node = *parsed_function().node_sequence();
106 ASSERT(sequence_node.length() == 2);
107 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode());
108 ASSERT(sequence_node.NodeAt(1)->IsReturnNode());
109 const StoreInstanceFieldNode& store_node =
110 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode();
111 __ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver. 73 __ movl(EAX, Address(ESP, 2 * kWordSize)); // Receiver.
112 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Value. 74 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Value.
113 __ StoreIntoObject(EAX, FieldAddress(EAX, store_node.field().Offset()), EBX); 75 __ StoreIntoObject(EAX, FieldAddress(EAX, offset), EBX);
114 const Immediate raw_null = 76 const Immediate raw_null =
115 Immediate(reinterpret_cast<intptr_t>(Object::null())); 77 Immediate(reinterpret_cast<intptr_t>(Object::null()));
116 __ movl(EAX, raw_null); 78 __ movl(EAX, raw_null);
117 __ ret(); 79 __ ret();
118 } 80 }
119 81
120 82
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
153
154 void FlowGraphCompiler::GenerateCallRuntime(intptr_t cid, 83 void FlowGraphCompiler::GenerateCallRuntime(intptr_t cid,
155 intptr_t token_index, 84 intptr_t token_index,
156 intptr_t try_index, 85 intptr_t try_index,
157 const RuntimeEntry& entry) { 86 const RuntimeEntry& entry) {
158 __ CallRuntime(entry); 87 __ CallRuntime(entry);
159 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index); 88 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index);
160 } 89 }
161 90
162 91
163 void FlowGraphCompiler::CopyParameters() { 92 void FlowGraphCompiler::CopyParameters() {
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 // at entry point. 366 // at entry point.
438 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode, 367 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode,
439 assembler()->CodeSize(), 368 assembler()->CodeSize(),
440 AstNode::kNoId, 369 AstNode::kNoId,
441 0, 370 0,
442 -1); 371 -1);
443 __ jmp(&StubCode::FixCallersTargetLabel()); 372 __ jmp(&StubCode::FixCallersTargetLabel());
444 } 373 }
445 374
446 375
447 void FlowGraphCompiler::EmitInstanceCall(intptr_t cid, 376 intptr_t FlowGraphCompiler::EmitInstanceCall(ExternalLabel* target_label,
448 intptr_t token_index, 377 const ICData& ic_data,
449 intptr_t try_index, 378 const Array& arguments_descriptor,
450 const String& function_name, 379 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); 380 __ LoadObject(ECX, ic_data);
461 __ LoadObject(EDX, arguments_descriptor); 381 __ LoadObject(EDX, arguments_descriptor);
462 382
463 uword label_address = 0; 383 __ call(target_label);
464 switch (checked_argument_count) { 384 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); 385 __ Drop(argument_count);
386 return descr_offset;
478 } 387 }
479 388
480 389
481 void FlowGraphCompiler::EmitStaticCall(intptr_t token_index, 390 intptr_t FlowGraphCompiler::EmitStaticCall(const Function& function,
482 intptr_t try_index, 391 const Array& arguments_descriptor,
483 const Function& function, 392 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); 393 __ LoadObject(ECX, function);
489 __ LoadObject(EDX, arguments_descriptor); 394 __ LoadObject(EDX, arguments_descriptor);
490 395 __ call(&StubCode::CallStaticFunctionLabel());
491 GenerateCall(token_index, 396 const intptr_t descr_offset = assembler()->CodeSize();
492 try_index,
493 &StubCode::CallStaticFunctionLabel(),
494 PcDescriptors::kFuncCall);
495 __ Drop(argument_count); 397 __ Drop(argument_count);
398 return descr_offset;
496 } 399 }
497 400
498 401
499 void FlowGraphCompiler::GenerateCall(intptr_t token_index, 402 void FlowGraphCompiler::GenerateCall(intptr_t token_index,
500 intptr_t try_index, 403 intptr_t try_index,
501 const ExternalLabel* label, 404 const ExternalLabel* label,
502 PcDescriptors::Kind kind) { 405 PcDescriptors::Kind kind) {
503 __ call(label); 406 __ call(label);
504 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index); 407 AddCurrentDescriptor(kind, AstNode::kNoId, token_index, try_index);
505 } 408 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 } 468 }
566 } 469 }
567 } 470 }
568 } 471 }
569 472
570 #undef __ 473 #undef __
571 474
572 } // namespace dart 475 } // namespace dart
573 476
574 #endif // defined TARGET_ARCH_IA32 477 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_ia32.h ('k') | runtime/vm/flow_graph_compiler_shared.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698