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

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

Issue 10538024: Implemented missing instructions in ia32, more sharing, removed bailouts, enable optimiziations on … (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_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/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/object_store.h" 13 #include "vm/object_store.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 #define __ compiler->assembler()-> 17 #define __ compiler->assembler()->
18 18
19 namespace dart { 19 namespace dart {
20 20
21 DECLARE_FLAG(int, optimization_counter_threshold); 21 DECLARE_FLAG(int, optimization_counter_threshold);
22 DECLARE_FLAG(bool, trace_functions); 22 DECLARE_FLAG(bool, trace_functions);
23 23
24 24
25 void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 25 void BindInstr::EmitNativeCode(FlowGraphCompilerShared* compiler) {
26 computation()->EmitNativeCode(compiler); 26 computation()->EmitNativeCode(compiler);
27 __ pushq(locs()->out().reg()); 27 __ pushq(locs()->out().reg());
28 } 28 }
29 29
30 30
31 LocationSummary* ReturnInstr::MakeLocationSummary() const { 31 LocationSummary* ReturnInstr::MakeLocationSummary() const {
32 const intptr_t kNumInputs = 1; 32 const intptr_t kNumInputs = 1;
33 const intptr_t kNumTemps = 1; 33 const intptr_t kNumTemps = 1;
34 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 34 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
35 locs->set_in(0, Location::RegisterLocation(RAX)); 35 locs->set_in(0, Location::RegisterLocation(RAX));
36 locs->set_temp(0, Location::RequiresRegister()); 36 locs->set_temp(0, Location::RequiresRegister());
37 return locs; 37 return locs;
38 } 38 }
39 39
40 40
41 void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 41 void ReturnInstr::EmitNativeCode(FlowGraphCompilerShared* compiler) {
42 Register result = locs()->in(0).reg(); 42 Register result = locs()->in(0).reg();
43 Register temp = locs()->temp(0).reg(); 43 Register temp = locs()->temp(0).reg();
44 ASSERT(result == RAX); 44 ASSERT(result == RAX);
45 if (!compiler->is_optimizing()) { 45 if (!compiler->is_optimizing()) {
46 // Count only in unoptimized code. 46 // Count only in unoptimized code.
47 // TODO(srdjan): Replace the counting code with a type feedback 47 // TODO(srdjan): Replace the counting code with a type feedback
48 // collection and counting stub. 48 // collection and counting stub.
49 const Function& function = 49 const Function& function =
50 Function::ZoneHandle(compiler->parsed_function().function().raw()); 50 Function::ZoneHandle(compiler->parsed_function().function().raw());
51 __ LoadObject(temp, function); 51 __ LoadObject(temp, function);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. 114 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
115 return result; 115 return result;
116 } 116 }
117 117
118 118
119 LocationSummary* LoadLocalComp::MakeLocationSummary() const { 119 LocationSummary* LoadLocalComp::MakeLocationSummary() const {
120 return LocationSummary::Make(0, Location::RequiresRegister()); 120 return LocationSummary::Make(0, Location::RequiresRegister());
121 } 121 }
122 122
123 123
124 void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { 124 void LoadLocalComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
125 Register result = locs()->out().reg(); 125 Register result = locs()->out().reg();
126 __ movq(result, Address(RBP, local().index() * kWordSize)); 126 __ movq(result, Address(RBP, local().index() * kWordSize));
127 } 127 }
128 128
129 129
130 LocationSummary* StoreLocalComp::MakeLocationSummary() const { 130 LocationSummary* StoreLocalComp::MakeLocationSummary() const {
131 return LocationSummary::Make(1, Location::SameAsFirstInput()); 131 return LocationSummary::Make(1, Location::SameAsFirstInput());
132 } 132 }
133 133
134 134
135 void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { 135 void StoreLocalComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
136 Register value = locs()->in(0).reg(); 136 Register value = locs()->in(0).reg();
137 Register result = locs()->out().reg(); 137 Register result = locs()->out().reg();
138 ASSERT(result == value); // Assert that register assignment is correct. 138 ASSERT(result == value); // Assert that register assignment is correct.
139 __ movq(Address(RBP, local().index() * kWordSize), value); 139 __ movq(Address(RBP, local().index() * kWordSize), value);
140 } 140 }
141 141
142 142
143 LocationSummary* ConstantVal::MakeLocationSummary() const { 143 LocationSummary* ConstantVal::MakeLocationSummary() const {
144 return LocationSummary::Make(0, Location::RequiresRegister()); 144 return LocationSummary::Make(0, Location::RequiresRegister());
145 } 145 }
146 146
147 147
148 void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { 148 void ConstantVal::EmitNativeCode(FlowGraphCompilerShared* compiler) {
149 Register result = locs()->out().reg(); 149 Register result = locs()->out().reg();
150 if (value().IsSmi()) { 150 if (value().IsSmi()) {
151 int64_t imm = reinterpret_cast<int64_t>(value().raw()); 151 int64_t imm = reinterpret_cast<int64_t>(value().raw());
152 __ movq(result, Immediate(imm)); 152 __ movq(result, Immediate(imm));
153 } else { 153 } else {
154 __ LoadObject(result, value()); 154 __ LoadObject(result, value());
155 } 155 }
156 } 156 }
157 157
158 158
159 LocationSummary* AssertAssignableComp::MakeLocationSummary() const { 159 LocationSummary* AssertAssignableComp::MakeLocationSummary() const {
160 LocationSummary* summary = new LocationSummary(3, 0); 160 LocationSummary* summary = new LocationSummary(3, 0);
161 summary->set_in(0, Location::RegisterLocation(RAX)); // Value. 161 summary->set_in(0, Location::RegisterLocation(RAX)); // Value.
162 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator. 162 summary->set_in(1, Location::RegisterLocation(RCX)); // Instantiator.
163 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments. 163 summary->set_in(2, Location::RegisterLocation(RDX)); // Type arguments.
164 summary->set_out(Location::RegisterLocation(RAX)); 164 summary->set_out(Location::RegisterLocation(RAX));
165 return summary; 165 return summary;
166 } 166 }
167 167
168 168
169 void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { 169 void AssertBooleanComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
170 Register obj = locs()->in(0).reg(); 170 Register obj = locs()->in(0).reg();
171 Register result = locs()->out().reg(); 171 Register result = locs()->out().reg();
172 172
173 // Check that the type of the value is allowed in conditional context. 173 // Check that the type of the value is allowed in conditional context.
174 // Call the runtime if the object is not bool::true or bool::false. 174 // Call the runtime if the object is not bool::true or bool::false.
175 Label done; 175 Label done;
176 __ CompareObject(obj, Bool::ZoneHandle(Bool::True())); 176 __ CompareObject(obj, Bool::ZoneHandle(Bool::True()));
177 __ j(EQUAL, &done, Assembler::kNearJump); 177 __ j(EQUAL, &done, Assembler::kNearJump);
178 __ CompareObject(obj, Bool::ZoneHandle(Bool::False())); 178 __ CompareObject(obj, Bool::ZoneHandle(Bool::False()));
179 __ j(EQUAL, &done, Assembler::kNearJump); 179 __ j(EQUAL, &done, Assembler::kNearJump);
(...skipping 14 matching lines...) Expand all
194 194
195 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 195 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
196 LocationSummary* locs = new LocationSummary(2, 0); 196 LocationSummary* locs = new LocationSummary(2, 0);
197 locs->set_in(0, Location::RequiresRegister()); 197 locs->set_in(0, Location::RequiresRegister());
198 locs->set_in(1, Location::RequiresRegister()); 198 locs->set_in(1, Location::RequiresRegister());
199 locs->set_out(Location::RegisterLocation(RAX)); 199 locs->set_out(Location::RegisterLocation(RAX));
200 return locs; 200 return locs;
201 } 201 }
202 202
203 203
204 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 204 void EqualityCompareComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
205 Register left = locs()->in(0).reg(); 205 Register left = locs()->in(0).reg();
206 Register right = locs()->in(1).reg(); 206 Register right = locs()->in(1).reg();
207 Register result = locs()->out().reg(); 207 Register result = locs()->out().reg();
208 ASSERT(locs()->out().reg() == RAX); 208 ASSERT(locs()->out().reg() == RAX);
209 209
210 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 210 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
211 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); 211 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
212 const Immediate raw_null = 212 const Immediate raw_null =
213 Immediate(reinterpret_cast<intptr_t>(Object::null())); 213 Immediate(reinterpret_cast<intptr_t>(Object::null()));
214 Label done, load_true, non_null_compare; 214 Label done, load_true, non_null_compare;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 LocationSummary* NativeCallComp::MakeLocationSummary() const { 246 LocationSummary* NativeCallComp::MakeLocationSummary() const {
247 LocationSummary* locs = new LocationSummary(0, 3); 247 LocationSummary* locs = new LocationSummary(0, 3);
248 locs->set_temp(0, Location::RegisterLocation(RAX)); 248 locs->set_temp(0, Location::RegisterLocation(RAX));
249 locs->set_temp(1, Location::RegisterLocation(RBX)); 249 locs->set_temp(1, Location::RegisterLocation(RBX));
250 locs->set_temp(2, Location::RegisterLocation(R10)); 250 locs->set_temp(2, Location::RegisterLocation(R10));
251 locs->set_out(Location::RequiresRegister()); 251 locs->set_out(Location::RequiresRegister());
252 return locs; 252 return locs;
253 } 253 }
254 254
255 255
256 void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 256 void NativeCallComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
257 ASSERT(locs()->temp(0).reg() == RAX); 257 ASSERT(locs()->temp(0).reg() == RAX);
258 ASSERT(locs()->temp(1).reg() == RBX); 258 ASSERT(locs()->temp(1).reg() == RBX);
259 ASSERT(locs()->temp(2).reg() == R10); 259 ASSERT(locs()->temp(2).reg() == R10);
260 Register result = locs()->out().reg(); 260 Register result = locs()->out().reg();
261 261
262 // Push the result place holder initialized to NULL. 262 // Push the result place holder initialized to NULL.
263 __ PushObject(Object::ZoneHandle()); 263 __ PushObject(Object::ZoneHandle());
264 // Pass a pointer to the first argument in RAX. 264 // Pass a pointer to the first argument in RAX.
265 if (!has_optional_parameters()) { 265 if (!has_optional_parameters()) {
266 __ leaq(RAX, Address(RBP, (1 + argument_count()) * kWordSize)); 266 __ leaq(RAX, Address(RBP, (1 + argument_count()) * kWordSize));
(...skipping 10 matching lines...) Expand all
277 __ popq(result); 277 __ popq(result);
278 } 278 }
279 279
280 280
281 LocationSummary* StoreIndexedComp::MakeLocationSummary() const { 281 LocationSummary* StoreIndexedComp::MakeLocationSummary() const {
282 const intptr_t kNumInputs = 3; 282 const intptr_t kNumInputs = 3;
283 return LocationSummary::Make(kNumInputs, Location::NoLocation()); 283 return LocationSummary::Make(kNumInputs, Location::NoLocation());
284 } 284 }
285 285
286 286
287 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 287 void StoreIndexedComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
288 Register receiver = locs()->in(0).reg(); 288 Register receiver = locs()->in(0).reg();
289 Register index = locs()->in(1).reg(); 289 Register index = locs()->in(1).reg();
290 Register value = locs()->in(2).reg(); 290 Register value = locs()->in(2).reg();
291 291
292 const String& function_name = 292 const String& function_name =
293 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); 293 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
294 294
295 __ pushq(receiver); 295 __ pushq(receiver);
296 __ pushq(index); 296 __ pushq(index);
297 __ pushq(value); 297 __ pushq(value);
298 const intptr_t kNumArguments = 3; 298 const intptr_t kNumArguments = 3;
299 const intptr_t kNumArgsChecked = 1; // Type-feedback. 299 const intptr_t kNumArgsChecked = 1; // Type-feedback.
300 compiler->GenerateInstanceCall(cid(), 300 compiler->GenerateInstanceCall(cid(),
301 token_index(), 301 token_index(),
302 try_index(), 302 try_index(),
303 function_name, 303 function_name,
304 kNumArguments, 304 kNumArguments,
305 Array::ZoneHandle(), // No optional arguments. 305 Array::ZoneHandle(), // No optional arguments.
306 kNumArgsChecked); 306 kNumArgsChecked);
307 } 307 }
308 308
309 309
310 LocationSummary* InstanceSetterComp::MakeLocationSummary() const { 310 LocationSummary* InstanceSetterComp::MakeLocationSummary() const {
311 const intptr_t kNumInputs = 2; 311 const intptr_t kNumInputs = 2;
312 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); 312 return LocationSummary::Make(kNumInputs, Location::RequiresRegister());
313 return NULL; 313 return NULL;
314 } 314 }
315 315
316 316
317 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { 317 void InstanceSetterComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
318 Register receiver = locs()->in(0).reg(); 318 Register receiver = locs()->in(0).reg();
319 Register value = locs()->in(1).reg(); 319 Register value = locs()->in(1).reg();
320 Register result = locs()->out().reg(); 320 Register result = locs()->out().reg();
321 321
322 // Preserve the value (second argument) under the arguments as the result 322 // Preserve the value (second argument) under the arguments as the result
323 // of the computation, then call the setter. 323 // of the computation, then call the setter.
324 const String& function_name = 324 const String& function_name =
325 String::ZoneHandle(Field::SetterSymbol(field_name())); 325 String::ZoneHandle(Field::SetterSymbol(field_name()));
326 326
327 // Insert a copy of the second (last) argument under the arguments. 327 // Insert a copy of the second (last) argument under the arguments.
(...skipping 13 matching lines...) Expand all
341 __ popq(result); 341 __ popq(result);
342 } 342 }
343 343
344 344
345 LocationSummary* StaticSetterComp::MakeLocationSummary() const { 345 LocationSummary* StaticSetterComp::MakeLocationSummary() const {
346 const intptr_t kNumInputs = 1; 346 const intptr_t kNumInputs = 1;
347 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); 347 return LocationSummary::Make(kNumInputs, Location::RequiresRegister());
348 } 348 }
349 349
350 350
351 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { 351 void StaticSetterComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
352 Register value = locs()->in(0).reg(); 352 Register value = locs()->in(0).reg();
353 Register result = locs()->out().reg(); 353 Register result = locs()->out().reg();
354 354
355 // Preserve the argument as the result of the computation, 355 // Preserve the argument as the result of the computation,
356 // then call the setter. 356 // then call the setter.
357 357
358 // Duplicate the argument. 358 // Duplicate the argument.
359 // TODO(fschneider): Avoid preserving the value if the result is not used. 359 // TODO(fschneider): Avoid preserving the value if the result is not used.
360 __ pushq(value); 360 __ pushq(value);
361 __ pushq(value); 361 __ pushq(value);
362 compiler->GenerateStaticCall(cid(), 362 compiler->GenerateStaticCall(cid(),
363 token_index(), 363 token_index(),
364 try_index(), 364 try_index(),
365 setter_function(), 365 setter_function(),
366 1, 366 1,
367 Array::ZoneHandle()); 367 Array::ZoneHandle());
368 __ popq(result); 368 __ popq(result);
369 } 369 }
370 370
371 371
372 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { 372 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const {
373 // TODO(fschneider): For this instruction the input register may be 373 // TODO(fschneider): For this instruction the input register may be
374 // reused for the result (but is not required to) because the input 374 // reused for the result (but is not required to) because the input
375 // is not used after the result is defined. We should consider adding 375 // is not used after the result is defined. We should consider adding
376 // this information to the input policy. 376 // this information to the input policy.
377 return LocationSummary::Make(1, Location::RequiresRegister()); 377 return LocationSummary::Make(1, Location::RequiresRegister());
378 } 378 }
379 379
380 380
381 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 381 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
382 Register instance = locs()->in(0).reg(); 382 Register instance = locs()->in(0).reg();
383 Register result = locs()->out().reg(); 383 Register result = locs()->out().reg();
384 384
385 __ movq(result, FieldAddress(instance, field().Offset())); 385 __ movq(result, FieldAddress(instance, field().Offset()));
386 } 386 }
387 387
388 388
389 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { 389 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const {
390 return LocationSummary::Make(0, Location::RequiresRegister()); 390 return LocationSummary::Make(0, Location::RequiresRegister());
391 } 391 }
392 392
393 393
394 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 394 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
395 Register result = locs()->out().reg(); 395 Register result = locs()->out().reg();
396 __ LoadObject(result, field()); 396 __ LoadObject(result, field());
397 __ movq(result, FieldAddress(result, Field::value_offset())); 397 __ movq(result, FieldAddress(result, Field::value_offset()));
398 } 398 }
399 399
400 400
401 LocationSummary* InstanceOfComp::MakeLocationSummary() const { 401 LocationSummary* InstanceOfComp::MakeLocationSummary() const {
402 LocationSummary* summary = new LocationSummary(3, 0); 402 LocationSummary* summary = new LocationSummary(3, 0);
403 summary->set_in(0, Location::RegisterLocation(RAX)); 403 summary->set_in(0, Location::RegisterLocation(RAX));
404 summary->set_in(1, Location::RegisterLocation(RCX)); 404 summary->set_in(1, Location::RegisterLocation(RCX));
405 summary->set_in(2, Location::RegisterLocation(RDX)); 405 summary->set_in(2, Location::RegisterLocation(RDX));
406 summary->set_out(Location::RegisterLocation(RAX)); 406 summary->set_out(Location::RegisterLocation(RAX));
407 return summary; 407 return summary;
408 } 408 }
409 409
410 410
411 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { 411 void InstanceOfComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
412 ASSERT(locs()->in(0).reg() == RAX); // Value. 412 ASSERT(locs()->in(0).reg() == RAX); // Value.
413 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. 413 ASSERT(locs()->in(1).reg() == RCX); // Instantiator.
414 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. 414 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments.
415 415
416 compiler->GenerateInstanceOf(cid(), 416 compiler->GenerateInstanceOf(cid(),
417 token_index(), 417 token_index(),
418 try_index(), 418 try_index(),
419 type(), 419 type(),
420 negate_result()); 420 negate_result());
421 ASSERT(locs()->out().reg() == RAX); 421 ASSERT(locs()->out().reg() == RAX);
422 } 422 }
423 423
424 424
425 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 425 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
426 // TODO(regis): The elements of the array could be considered as arguments to 426 // TODO(regis): The elements of the array could be considered as arguments to
427 // CreateArrayComp, thereby making CreateArrayComp a call. 427 // CreateArrayComp, thereby making CreateArrayComp a call.
428 // For VerifyCallComputation to work, CreateArrayComp would need an 428 // For VerifyCallComputation to work, CreateArrayComp would need an
429 // ArgumentCount getter and an ArgumentAt getter. 429 // ArgumentCount getter and an ArgumentAt getter.
430 const intptr_t kNumInputs = 1; 430 const intptr_t kNumInputs = 1;
431 const intptr_t kNumTemps = 1; 431 const intptr_t kNumTemps = 1;
432 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 432 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
433 locs->set_in(0, Location::RegisterLocation(RBX)); 433 locs->set_in(0, Location::RegisterLocation(RBX));
434 locs->set_temp(0, Location::RegisterLocation(R10)); 434 locs->set_temp(0, Location::RegisterLocation(R10));
435 locs->set_out(Location::RegisterLocation(RAX)); 435 locs->set_out(Location::RegisterLocation(RAX));
436 return locs; 436 return locs;
437 } 437 }
438 438
439 439
440 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 440 void CreateArrayComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
441 Register temp_reg = locs()->temp(0).reg(); 441 Register temp_reg = locs()->temp(0).reg();
442 Register result_reg = locs()->out().reg(); 442 Register result_reg = locs()->out().reg();
443 443
444 // 1. Allocate the array. R10 = length, RBX = element type. 444 // 1. Allocate the array. R10 = length, RBX = element type.
445 ASSERT(temp_reg == R10); 445 ASSERT(temp_reg == R10);
446 ASSERT(locs()->in(0).reg() == RBX); 446 ASSERT(locs()->in(0).reg() == RBX);
447 __ movq(temp_reg, Immediate(Smi::RawValue(ElementCount()))); 447 __ movq(temp_reg, Immediate(Smi::RawValue(ElementCount())));
448 compiler->GenerateCall(token_index(), 448 compiler->GenerateCall(token_index(),
449 try_index(), 449 try_index(),
450 &StubCode::AllocateArrayLabel(), 450 &StubCode::AllocateArrayLabel(),
451 PcDescriptors::kOther); 451 PcDescriptors::kOther);
452 ASSERT(result_reg == RAX); 452 ASSERT(result_reg == RAX);
453 // 2. Initialize the array in result_reg with the element values. 453 // 2. Initialize the array in result_reg with the element values.
454 __ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset())); 454 __ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset()));
455 for (int i = ElementCount() - 1; i >= 0; --i) { 455 for (int i = ElementCount() - 1; i >= 0; --i) {
456 ASSERT(ElementAt(i)->IsUse()); 456 ASSERT(ElementAt(i)->IsUse());
457 __ popq(Address(temp_reg, i * kWordSize)); 457 __ popq(Address(temp_reg, i * kWordSize));
458 } 458 }
459 } 459 }
460 460
461 461
462 LocationSummary* AllocateObjectWithBoundsCheckComp:: 462 LocationSummary* AllocateObjectWithBoundsCheckComp::
463 MakeLocationSummary() const { 463 MakeLocationSummary() const {
464 return LocationSummary::Make(2, Location::RequiresRegister()); 464 return LocationSummary::Make(2, Location::RequiresRegister());
465 } 465 }
466 466
467 467
468 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( 468 void AllocateObjectWithBoundsCheckComp::EmitNativeCode(
469 FlowGraphCompiler* compiler) { 469 FlowGraphCompilerShared* compiler) {
470 const Class& cls = Class::ZoneHandle(constructor().owner()); 470 const Class& cls = Class::ZoneHandle(constructor().owner());
471 Register type_arguments = locs()->in(0).reg(); 471 Register type_arguments = locs()->in(0).reg();
472 Register instantiator_type_arguments = locs()->in(1).reg(); 472 Register instantiator_type_arguments = locs()->in(1).reg();
473 Register result = locs()->out().reg(); 473 Register result = locs()->out().reg();
474 474
475 // Push the result place holder initialized to NULL. 475 // Push the result place holder initialized to NULL.
476 __ PushObject(Object::ZoneHandle()); 476 __ PushObject(Object::ZoneHandle());
477 __ pushq(Immediate(Smi::RawValue(token_index()))); 477 __ pushq(Immediate(Smi::RawValue(token_index())));
478 __ PushObject(cls); 478 __ PushObject(cls);
479 __ pushq(type_arguments); 479 __ pushq(type_arguments);
480 __ pushq(instantiator_type_arguments); 480 __ pushq(instantiator_type_arguments);
481 compiler->GenerateCallRuntime(cid(), 481 compiler->GenerateCallRuntime(cid(),
482 token_index(), 482 token_index(),
483 try_index(), 483 try_index(),
484 kAllocateObjectWithBoundsCheckRuntimeEntry); 484 kAllocateObjectWithBoundsCheckRuntimeEntry);
485 // Pop instantiator type arguments, type arguments, class, and 485 // Pop instantiator type arguments, type arguments, class, and
486 // source location. 486 // source location.
487 __ Drop(4); 487 __ Drop(4);
488 __ popq(result); // Pop new instance. 488 __ popq(result); // Pop new instance.
489 } 489 }
490 490
491 491
492 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 492 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
493 return LocationSummary::Make(1, Location::RequiresRegister()); 493 return LocationSummary::Make(1, Location::RequiresRegister());
494 } 494 }
495 495
496 496
497 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 497 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
498 Register obj = locs()->in(0).reg(); 498 Register obj = locs()->in(0).reg();
499 Register result = locs()->out().reg(); 499 Register result = locs()->out().reg();
500 500
501 __ movq(result, FieldAddress(obj, offset_in_bytes())); 501 __ movq(result, FieldAddress(obj, offset_in_bytes()));
502 } 502 }
503 503
504 504
505 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { 505 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const {
506 const intptr_t kNumInputs = 1; 506 const intptr_t kNumInputs = 1;
507 const intptr_t kNumTemps = 0; 507 const intptr_t kNumTemps = 0;
508 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 508 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
509 locs->set_in(0, Location::RequiresRegister()); 509 locs->set_in(0, Location::RequiresRegister());
510 locs->set_out(Location::SameAsFirstInput()); 510 locs->set_out(Location::SameAsFirstInput());
511 return locs; 511 return locs;
512 } 512 }
513 513
514 514
515 void InstantiateTypeArgumentsComp::EmitNativeCode(FlowGraphCompiler* compiler) { 515 void InstantiateTypeArgumentsComp::EmitNativeCode(
516 FlowGraphCompilerShared* compiler) {
516 Register instantiator_reg = locs()->in(0).reg(); 517 Register instantiator_reg = locs()->in(0).reg();
517 Register result_reg = locs()->out().reg(); 518 Register result_reg = locs()->out().reg();
518 519
519 // 'instantiator_reg' is the instantiator AbstractTypeArguments object 520 // 'instantiator_reg' is the instantiator AbstractTypeArguments object
520 // (or null). 521 // (or null).
521 // If the instantiator is null and if the type argument vector 522 // If the instantiator is null and if the type argument vector
522 // instantiated from null becomes a vector of Dynamic, then use null as 523 // instantiated from null becomes a vector of Dynamic, then use null as
523 // the type arguments. 524 // the type arguments.
524 Label type_arguments_instantiated; 525 Label type_arguments_instantiated;
525 const intptr_t len = type_arguments().Length(); 526 const intptr_t len = type_arguments().Length();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 const intptr_t kNumInputs = 1; 566 const intptr_t kNumInputs = 1;
566 const intptr_t kNumTemps = 0; 567 const intptr_t kNumTemps = 0;
567 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 568 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
568 locs->set_in(0, Location::RequiresRegister()); 569 locs->set_in(0, Location::RequiresRegister());
569 locs->set_out(Location::SameAsFirstInput()); 570 locs->set_out(Location::SameAsFirstInput());
570 return locs; 571 return locs;
571 } 572 }
572 573
573 574
574 void ExtractConstructorTypeArgumentsComp::EmitNativeCode( 575 void ExtractConstructorTypeArgumentsComp::EmitNativeCode(
575 FlowGraphCompiler* compiler) { 576 FlowGraphCompilerShared* compiler) {
576 Register instantiator_reg = locs()->in(0).reg(); 577 Register instantiator_reg = locs()->in(0).reg();
577 Register result_reg = locs()->out().reg(); 578 Register result_reg = locs()->out().reg();
578 ASSERT(instantiator_reg == result_reg); 579 ASSERT(instantiator_reg == result_reg);
579 580
580 // instantiator_reg is the instantiator type argument vector, i.e. an 581 // instantiator_reg is the instantiator type argument vector, i.e. an
581 // AbstractTypeArguments object (or null). 582 // AbstractTypeArguments object (or null).
582 // If the instantiator is null and if the type argument vector 583 // If the instantiator is null and if the type argument vector
583 // instantiated from null becomes a vector of Dynamic, then use null as 584 // instantiated from null becomes a vector of Dynamic, then use null as
584 // the type arguments. 585 // the type arguments.
585 Label type_arguments_instantiated; 586 Label type_arguments_instantiated;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 const intptr_t kNumInputs = 1; 621 const intptr_t kNumInputs = 1;
621 const intptr_t kNumTemps = 0; 622 const intptr_t kNumTemps = 0;
622 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 623 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
623 locs->set_in(0, Location::RequiresRegister()); 624 locs->set_in(0, Location::RequiresRegister());
624 locs->set_out(Location::SameAsFirstInput()); 625 locs->set_out(Location::SameAsFirstInput());
625 return locs; 626 return locs;
626 } 627 }
627 628
628 629
629 void ExtractConstructorInstantiatorComp::EmitNativeCode( 630 void ExtractConstructorInstantiatorComp::EmitNativeCode(
630 FlowGraphCompiler* compiler) { 631 FlowGraphCompilerShared* compiler) {
631 ASSERT(instantiator()->IsUse()); 632 ASSERT(instantiator()->IsUse());
632 Register instantiator_reg = locs()->in(0).reg(); 633 Register instantiator_reg = locs()->in(0).reg();
633 ASSERT(locs()->out().reg() == instantiator_reg); 634 ASSERT(locs()->out().reg() == instantiator_reg);
634 635
635 // instantiator_reg is the instantiator AbstractTypeArguments object 636 // instantiator_reg is the instantiator AbstractTypeArguments object
636 // (or null). If the instantiator is null and if the type argument vector 637 // (or null). If the instantiator is null and if the type argument vector
637 // instantiated from null becomes a vector of Dynamic, then use null as 638 // instantiated from null becomes a vector of Dynamic, then use null as
638 // the type arguments and do not pass the instantiator. 639 // the type arguments and do not pass the instantiator.
639 Label done; 640 Label done;
640 const intptr_t len = type_arguments().Length(); 641 const intptr_t len = type_arguments().Length();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 LocationSummary* AllocateContextComp::MakeLocationSummary() const { 684 LocationSummary* AllocateContextComp::MakeLocationSummary() const {
684 const intptr_t kNumInputs = 0; 685 const intptr_t kNumInputs = 0;
685 const intptr_t kNumTemps = 1; 686 const intptr_t kNumTemps = 1;
686 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 687 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
687 locs->set_temp(0, Location::RegisterLocation(R10)); 688 locs->set_temp(0, Location::RegisterLocation(R10));
688 locs->set_out(Location::RegisterLocation(RAX)); 689 locs->set_out(Location::RegisterLocation(RAX));
689 return locs; 690 return locs;
690 } 691 }
691 692
692 693
693 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 694 void AllocateContextComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
694 ASSERT(locs()->temp(0).reg() == R10); 695 ASSERT(locs()->temp(0).reg() == R10);
695 696
696 __ movq(R10, Immediate(num_context_variables())); 697 __ movq(R10, Immediate(num_context_variables()));
697 const ExternalLabel label("alloc_context", 698 const ExternalLabel label("alloc_context",
698 StubCode::AllocateContextEntryPoint()); 699 StubCode::AllocateContextEntryPoint());
699 compiler->GenerateCall(token_index(), 700 compiler->GenerateCall(token_index(),
700 try_index(), 701 try_index(),
701 &label, 702 &label,
702 PcDescriptors::kOther); 703 PcDescriptors::kOther);
703 } 704 }
704 705
705 706
706 LocationSummary* CloneContextComp::MakeLocationSummary() const { 707 LocationSummary* CloneContextComp::MakeLocationSummary() const {
707 return LocationSummary::Make(1, Location::RequiresRegister()); 708 return LocationSummary::Make(1, Location::RequiresRegister());
708 } 709 }
709 710
710 711
711 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 712 void CloneContextComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
712 Register context_value = locs()->in(0).reg(); 713 Register context_value = locs()->in(0).reg();
713 Register result = locs()->out().reg(); 714 Register result = locs()->out().reg();
714 715
715 __ PushObject(Object::ZoneHandle()); // Make room for the result. 716 __ PushObject(Object::ZoneHandle()); // Make room for the result.
716 __ pushq(context_value); 717 __ pushq(context_value);
717 compiler->GenerateCallRuntime(cid(), 718 compiler->GenerateCallRuntime(cid(),
718 token_index(), 719 token_index(),
719 try_index(), 720 try_index(),
720 kCloneContextRuntimeEntry); 721 kCloneContextRuntimeEntry);
721 __ popq(result); // Remove argument. 722 __ popq(result); // Remove argument.
722 __ popq(result); // Get result (cloned context). 723 __ popq(result); // Get result (cloned context).
723 } 724 }
724 725
725 726
726 LocationSummary* CatchEntryComp::MakeLocationSummary() const { 727 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
727 return LocationSummary::Make(0, Location::NoLocation()); 728 return LocationSummary::Make(0, Location::NoLocation());
728 } 729 }
729 730
730 731
731 // Restore stack and initialize the two exception variables: 732 // Restore stack and initialize the two exception variables:
732 // exception and stack trace variables. 733 // exception and stack trace variables.
733 void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { 734 void CatchEntryComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
734 // Restore RSP from RBP as we are coming from a throw and the code for 735 // Restore RSP from RBP as we are coming from a throw and the code for
735 // popping arguments has not been run. 736 // popping arguments has not been run.
736 const intptr_t locals_space_size = compiler->StackSize() * kWordSize; 737 const intptr_t locals_space_size = compiler->StackSize() * kWordSize;
737 ASSERT(locals_space_size >= 0); 738 ASSERT(locals_space_size >= 0);
738 const intptr_t offset_size = 739 const intptr_t offset_size =
739 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; 740 -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP;
740 __ leaq(RSP, Address(RBP, offset_size)); 741 __ leaq(RSP, Address(RBP, offset_size));
741 742
742 ASSERT(!exception_var().is_captured()); 743 ASSERT(!exception_var().is_captured());
743 ASSERT(!stacktrace_var().is_captured()); 744 ASSERT(!stacktrace_var().is_captured());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 summary->set_in(0, Location::RequiresRegister()); 785 summary->set_in(0, Location::RequiresRegister());
785 summary->set_in(1, Location::RequiresRegister()); 786 summary->set_in(1, Location::RequiresRegister());
786 summary->set_out(Location::SameAsFirstInput()); 787 summary->set_out(Location::SameAsFirstInput());
787 summary->set_temp(0, Location::RequiresRegister()); 788 summary->set_temp(0, Location::RequiresRegister());
788 return summary; 789 return summary;
789 } 790 }
790 } 791 }
791 792
792 793
793 // TODO(srdjan): Implement variations. 794 // TODO(srdjan): Implement variations.
794 static bool TryEmitSmiBinaryOp(FlowGraphCompiler* compiler, 795 static bool TryEmitSmiBinaryOp(FlowGraphCompilerShared* compiler,
795 BinaryOpComp* comp) { 796 BinaryOpComp* comp) {
796 ASSERT((comp->ic_data() != NULL)); 797 ASSERT((comp->ic_data() != NULL));
797 const ICData& ic_data = *comp->ic_data(); 798 const ICData& ic_data = *comp->ic_data();
798 if (ic_data.IsNull()) return false; 799 if (ic_data.IsNull()) return false;
799 if (ic_data.num_args_tested() != 2) return false; 800 if (ic_data.num_args_tested() != 2) return false;
800 if (ic_data.NumberOfChecks() != 1) return false; 801 if (ic_data.NumberOfChecks() != 1) return false;
801 Function& target = Function::Handle(); 802 Function& target = Function::Handle();
802 GrowableArray<const Class*> classes; 803 GrowableArray<const Class*> classes;
803 ic_data.GetCheckAt(0, &classes, &target); 804 ic_data.GetCheckAt(0, &classes, &target);
804 const Class& smi_class = 805 const Class& smi_class =
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 UNREACHABLE(); 930 UNREACHABLE();
930 return false; 931 return false;
931 } 932 }
932 default: 933 default:
933 UNREACHABLE(); 934 UNREACHABLE();
934 return false; 935 return false;
935 } 936 }
936 return true; 937 return true;
937 } 938 }
938 939
939 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 940 void BinaryOpComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
940 if (TryEmitSmiBinaryOp(compiler, this)) { 941 if (TryEmitSmiBinaryOp(compiler, this)) {
941 // Operation inlined. 942 // Operation inlined.
942 return; 943 return;
943 } 944 }
944 // TODO(srdjan): Remove this code once BinaryOpComp has been implemeneted 945 // TODO(srdjan): Remove this code once BinaryOpComp has been implemeneted
945 // for all intended operations. 946 // for all intended operations.
946 Register left = locs()->in(0).reg(); 947 Register left = locs()->in(0).reg();
947 Register right = locs()->in(1).reg(); 948 Register right = locs()->in(1).reg();
948 __ pushq(left); 949 __ pushq(left);
949 __ pushq(right); 950 __ pushq(right);
950 InstanceCallComp* instance_call_comp = instance_call(); 951 InstanceCallComp* instance_call_comp = instance_call();
951 instance_call_comp->EmitNativeCode(compiler); 952 instance_call_comp->EmitNativeCode(compiler);
952 if (locs()->out().reg() != RAX) { 953 if (locs()->out().reg() != RAX) {
953 __ movq(locs()->out().reg(), RAX); 954 __ movq(locs()->out().reg(), RAX);
954 } 955 }
955 } 956 }
956 957
957 958
958 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const { 959 LocationSummary* UnarySmiOpComp::MakeLocationSummary() const {
959 const intptr_t kNumInputs = 1; 960 const intptr_t kNumInputs = 1;
960 const intptr_t kNumTemps = 0; 961 const intptr_t kNumTemps = 0;
961 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 962 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
962 summary->set_in(0, Location::RequiresRegister()); 963 summary->set_in(0, Location::RequiresRegister());
963 summary->set_out(Location::SameAsFirstInput()); 964 summary->set_out(Location::SameAsFirstInput());
964 return summary; 965 return summary;
965 } 966 }
966 967
967 968
968 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 969 void UnarySmiOpComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
969 const ICData& ic_data = *instance_call()->ic_data(); 970 const ICData& ic_data = *instance_call()->ic_data();
970 ASSERT(!ic_data.IsNull()); 971 ASSERT(!ic_data.IsNull());
971 ASSERT(ic_data.num_args_tested() == 1); 972 ASSERT(ic_data.num_args_tested() == 1);
972 // TODO(srdjan): Implement for more checks. 973 // TODO(srdjan): Implement for more checks.
973 ASSERT(ic_data.NumberOfChecks() == 1); 974 ASSERT(ic_data.NumberOfChecks() == 1);
974 Class& test_class = Class::Handle(); 975 Class& test_class = Class::Handle();
975 Function& target = Function::Handle(); 976 Function& target = Function::Handle();
976 ic_data.GetOneClassCheckAt(0, &test_class, &target); 977 ic_data.GetOneClassCheckAt(0, &test_class, &target);
977 978
978 Register value = locs()->in(0).reg(); 979 Register value = locs()->in(0).reg();
(...skipping 30 matching lines...) Expand all
1009 const intptr_t kNumInputs = 1; 1010 const intptr_t kNumInputs = 1;
1010 const intptr_t kNumTemps = 1; // Needed for doubles. 1011 const intptr_t kNumTemps = 1; // Needed for doubles.
1011 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); 1012 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
1012 summary->set_in(0, Location::RequiresRegister()); 1013 summary->set_in(0, Location::RequiresRegister());
1013 summary->set_out(Location::SameAsFirstInput()); 1014 summary->set_out(Location::SameAsFirstInput());
1014 summary->set_temp(0, Location::RequiresRegister()); 1015 summary->set_temp(0, Location::RequiresRegister());
1015 return summary; 1016 return summary;
1016 } 1017 }
1017 1018
1018 1019
1019 void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1020 void NumberNegateComp::EmitNativeCode(FlowGraphCompilerShared* compiler) {
1020 const ICData& ic_data = *instance_call()->ic_data(); 1021 const ICData& ic_data = *instance_call()->ic_data();
1021 ASSERT(!ic_data.IsNull()); 1022 ASSERT(!ic_data.IsNull());
1022 ASSERT(ic_data.num_args_tested() == 1); 1023 ASSERT(ic_data.num_args_tested() == 1);
1023 1024
1024 // TODO(srdjan): Implement for more checks. 1025 // TODO(srdjan): Implement for more checks.
1025 ASSERT(ic_data.NumberOfChecks() == 1); 1026 ASSERT(ic_data.NumberOfChecks() == 1);
1026 Class& test_class = Class::Handle(); 1027 Class& test_class = Class::Handle();
1027 Function& target = Function::Handle(); 1028 Function& target = Function::Handle();
1028 ic_data.GetOneClassCheckAt(0, &test_class, &target); 1029 ic_data.GetOneClassCheckAt(0, &test_class, &target);
1029 1030
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 } else { 1064 } else {
1064 UNREACHABLE(); 1065 UNREACHABLE();
1065 } 1066 }
1066 } 1067 }
1067 1068
1068 } // namespace dart 1069 } // namespace dart
1069 1070
1070 #undef __ 1071 #undef __
1071 1072
1072 #endif // defined TARGET_ARCH_X64 1073 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/flow_graph_compiler_shared.h ('K') | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698