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

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

Issue 9570015: Support instance getters and setters, indexed loads and stores. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 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_x64.h ('k') | runtime/vm/intermediate_language.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_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
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;
srdjan 2012/03/01 23:19:31 Can you check that last temp is on TOS, i.e., with
Kevin Millikin (Google) 2012/03/02 09:01:28 We can't easily check that it's actually on top of
86 }
87
88
89 void FlowGraphCompiler::EmitInstanceCall(intptr_t node_id,
90 intptr_t token_index,
91 const String& function_name,
92 intptr_t argument_count,
93 const Array& argument_names,
94 intptr_t checked_argument_count) {
95 ICData& ic_data =
96 ICData::ZoneHandle(ICData::New(parsed_function_.function(),
97 function_name,
98 node_id,
99 checked_argument_count));
100 const Array& arguments_descriptor =
101 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names);
102 __ LoadObject(RBX, ic_data);
103 __ LoadObject(R10, arguments_descriptor);
104
105 uword label_address = 0;
106 switch (checked_argument_count) {
107 case 1:
108 label_address = StubCode::OneArgCheckInlineCacheEntryPoint();
109 break;
110 case 2:
111 label_address = StubCode::TwoArgsCheckInlineCacheEntryPoint();
112 break;
113 default:
114 UNIMPLEMENTED();
115 }
116 ExternalLabel target_label("InlineCache", label_address);
117 __ call(&target_label);
118 AddCurrentDescriptor(PcDescriptors::kIcCall, node_id, token_index);
119 __ addq(RSP, Immediate(argument_count * kWordSize));
120 }
121
122
69 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) { 123 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) {
70 Bailout("InstanceCallComp"); 124 ASSERT(VerifyCallComputation(comp));
125 EmitInstanceCall(comp->node_id(),
126 comp->token_index(),
127 comp->function_name(),
128 comp->ArgumentCount(),
129 comp->argument_names(),
130 comp->checked_argument_count());
71 } 131 }
72 132
73 133
74 void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) { 134 void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) {
75 Bailout("StrictCompareComp"); 135 Bailout("StrictCompareComp");
76 } 136 }
77 137
78 138
79 139
80 void FlowGraphCompiler::VisitStaticCall(StaticCallComp* comp) { 140 void FlowGraphCompiler::VisitStaticCall(StaticCallComp* comp) {
81 Bailout("StaticCallComp"); 141 ASSERT(VerifyCallComputation(comp));
142
143 int argument_count = comp->ArgumentCount();
144 const Array& arguments_descriptor =
145 CodeGenerator::ArgumentsDescriptor(argument_count,
146 comp->argument_names());
147 __ LoadObject(RBX, comp->function());
148 __ LoadObject(R10, arguments_descriptor);
149
150 GenerateCall(comp->token_index(),
151 &StubCode::CallStaticFunctionLabel(),
152 PcDescriptors::kFuncCall);
153 __ addq(RSP, Immediate(argument_count * kWordSize));
82 } 154 }
83 155
84 156
85 void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) { 157 void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) {
86 if (comp->local().is_captured()) { 158 if (comp->local().is_captured()) {
87 Bailout("load of context variable"); 159 Bailout("load of context variable");
88 } 160 }
89 __ movq(RAX, Address(RBP, comp->local().index() * kWordSize)); 161 __ movq(RAX, Address(RBP, comp->local().index() * kWordSize));
90 } 162 }
91 163
92 164
93 void FlowGraphCompiler::VisitStoreLocal(StoreLocalComp* comp) { 165 void FlowGraphCompiler::VisitStoreLocal(StoreLocalComp* comp) {
94 if (comp->local().is_captured()) { 166 if (comp->local().is_captured()) {
95 Bailout("store to context variable"); 167 Bailout("store to context variable");
96 } 168 }
97 LoadValue(comp->value()); 169 LoadValue(comp->value());
98 __ movq(Address(RBP, comp->local().index() * kWordSize), RAX); 170 __ movq(Address(RBP, comp->local().index() * kWordSize), RAX);
99 } 171 }
100 172
101 173
174 void FlowGraphCompiler::VisitStoreIndexed(StoreIndexedComp* comp) {
175 // Call operator []= but preserve the third argument value under the
176 // arguments as the result of the computation.
177 const String& function_name =
178 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
179 // Placeholder is under value, index, and receiver.
180 const int kPlaceholderOffset = 3 * kWordSize;
181 __ movq(RAX, Address(RSP, 0)); // Value.
182 __ movq(Address(RSP, kPlaceholderOffset), RAX);
183 EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 3,
184 Array::ZoneHandle(), 1);
185 __ popq(RAX);
186 }
187
188
189 void FlowGraphCompiler::VisitInstanceSetter(InstanceSetterComp* comp) {
190 // Preserve the second argument under the arguments as the result of the
191 // computation, then call the getter.
srdjan 2012/03/01 23:19:31 Can you verify that place holder, value, array and
Kevin Millikin (Google) 2012/03/02 09:01:28 Yes.
192 const String& function_name =
193 String::ZoneHandle(Field::SetterSymbol(comp->field_name()));
194 // Placeholder is under value and receiver.
195 const int kPlaceholderOffset = 2 * kWordSize;
196 __ movq(RAX, Address(RSP, 0)); // Value.
197 __ movq(Address(RSP, kPlaceholderOffset), RAX);
198 EmitInstanceCall(comp->node_id(), comp->token_index(), function_name, 2,
199 Array::ZoneHandle(), 1);
200 __ popq(RAX);
201 }
202
203
102 void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) { 204 void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) {
103 Bailout("JoinEntryInstr"); 205 Bailout("JoinEntryInstr");
104 } 206 }
105 207
106 208
107 void FlowGraphCompiler::VisitTargetEntry(TargetEntryInstr* instr) { 209 void FlowGraphCompiler::VisitTargetEntry(TargetEntryInstr* instr) {
108 // Since we don't handle branching control flow yet, there is nothing to do. 210 // Since we don't handle branching control flow yet, there is nothing to do.
109 } 211 }
110 212
111 213
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode, 353 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode,
252 assembler_->CodeSize(), 354 assembler_->CodeSize(),
253 AstNode::kNoId, 355 AstNode::kNoId,
254 0, 356 0,
255 -1); 357 -1);
256 __ jmp(&StubCode::FixCallersTargetLabel()); 358 __ jmp(&StubCode::FixCallersTargetLabel());
257 } 359 }
258 360
259 361
260 // Infrastructure copied from class CodeGenerator. 362 // Infrastructure copied from class CodeGenerator.
363 void FlowGraphCompiler::GenerateCall(intptr_t token_index,
364 const ExternalLabel* label,
365 PcDescriptors::Kind kind) {
366 __ call(label);
367 AddCurrentDescriptor(kind, AstNode::kNoId, token_index);
368 }
369
370
261 void FlowGraphCompiler::GenerateCallRuntime(intptr_t node_id, 371 void FlowGraphCompiler::GenerateCallRuntime(intptr_t node_id,
262 intptr_t token_index, 372 intptr_t token_index,
263 const RuntimeEntry& entry) { 373 const RuntimeEntry& entry) {
264 __ CallRuntimeFromDart(entry); 374 __ CallRuntimeFromDart(entry);
265 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index); 375 AddCurrentDescriptor(PcDescriptors::kOther, node_id, token_index);
266 } 376 }
267 377
268 378
269 // Uses current pc position and try-index. 379 // Uses current pc position and try-index.
270 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, 380 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind,
(...skipping 26 matching lines...) Expand all
297 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) { 407 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
298 // We don't compile exception handlers yet. 408 // We don't compile exception handlers yet.
299 code.set_exception_handlers( 409 code.set_exception_handlers(
300 ExceptionHandlers::Handle(ExceptionHandlers::New(0))); 410 ExceptionHandlers::Handle(ExceptionHandlers::New(0)));
301 } 411 }
302 412
303 413
304 } // namespace dart 414 } // namespace dart
305 415
306 #endif // defined TARGET_ARCH_X64 416 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_x64.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698