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

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

Issue 10832150: Get rid of ast node ids. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('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/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 __ Bind(&not_yet_hot); 81 __ Bind(&not_yet_hot);
82 __ Bind(&already_optimized); 82 __ Bind(&already_optimized);
83 } 83 }
84 } 84 }
85 if (FLAG_trace_functions) { 85 if (FLAG_trace_functions) {
86 const Function& function = 86 const Function& function =
87 Function::ZoneHandle(compiler->parsed_function().function().raw()); 87 Function::ZoneHandle(compiler->parsed_function().function().raw());
88 __ LoadObject(temp, function); 88 __ LoadObject(temp, function);
89 __ pushl(result); // Preserve result. 89 __ pushl(result); // Preserve result.
90 __ pushl(temp); 90 __ pushl(temp);
91 compiler->GenerateCallRuntime(AstNode::kNoId, 91 compiler->GenerateCallRuntime(Isolate::kNoDeoptId,
92 0, 92 0,
93 CatchClauseNode::kInvalidTryIndex, 93 CatchClauseNode::kInvalidTryIndex,
94 kTraceFunctionExitRuntimeEntry); 94 kTraceFunctionExitRuntimeEntry);
95 __ popl(temp); // Remove argument. 95 __ popl(temp); // Remove argument.
96 __ popl(result); // Restore result. 96 __ popl(result); // Restore result.
97 } 97 }
98 __ LeaveFrame(); 98 __ LeaveFrame();
99 __ ret(); 99 __ ret();
100 100
101 // Generate 1 byte NOP so that the debugger can patch the 101 // Generate 1 byte NOP so that the debugger can patch the
102 // return pattern with a call to the debug stub. 102 // return pattern with a call to the debug stub.
103 __ nop(1); 103 __ nop(1);
104 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 104 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
105 cid(), 105 deopt_id(),
106 token_pos(), 106 token_pos(),
107 CatchClauseNode::kInvalidTryIndex); 107 CatchClauseNode::kInvalidTryIndex);
108 } 108 }
109 109
110 110
111 LocationSummary* ClosureCallComp::MakeLocationSummary() const { 111 LocationSummary* ClosureCallComp::MakeLocationSummary() const {
112 const intptr_t kNumInputs = 0; 112 const intptr_t kNumInputs = 0;
113 const intptr_t kNumTemps = 1; 113 const intptr_t kNumTemps = 1;
114 LocationSummary* result = 114 LocationSummary* result =
115 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 115 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 190
191 // Check that the type of the value is allowed in conditional context. 191 // Check that the type of the value is allowed in conditional context.
192 // Call the runtime if the object is not bool::true or bool::false. 192 // Call the runtime if the object is not bool::true or bool::false.
193 Label done; 193 Label done;
194 __ CompareObject(obj, compiler->bool_true()); 194 __ CompareObject(obj, compiler->bool_true());
195 __ j(EQUAL, &done, Assembler::kNearJump); 195 __ j(EQUAL, &done, Assembler::kNearJump);
196 __ CompareObject(obj, compiler->bool_false()); 196 __ CompareObject(obj, compiler->bool_false());
197 __ j(EQUAL, &done, Assembler::kNearJump); 197 __ j(EQUAL, &done, Assembler::kNearJump);
198 198
199 __ pushl(obj); // Push the source object. 199 __ pushl(obj); // Push the source object.
200 compiler->GenerateCallRuntime(cid(), 200 compiler->GenerateCallRuntime(deopt_id(),
201 token_pos(), 201 token_pos(),
202 try_index(), 202 try_index(),
203 kConditionTypeErrorRuntimeEntry); 203 kConditionTypeErrorRuntimeEntry);
204 // We should never return here. 204 // We should never return here.
205 __ int3(); 205 __ int3();
206 206
207 __ Bind(&done); 207 __ Bind(&done);
208 ASSERT(obj == result); 208 ASSERT(obj == result);
209 } 209 }
210 210
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 } 257 }
258 258
259 259
260 // Optional integer arguments can often be null. Null is not collected 260 // Optional integer arguments can often be null. Null is not collected
261 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well? 261 // by IC data. TODO(srdjan): Shall we collect null classes in ICData as well?
262 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler, 262 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler,
263 EqualityCompareComp* comp) { 263 EqualityCompareComp* comp) {
264 Register left = comp->locs()->in(0).reg(); 264 Register left = comp->locs()->in(0).reg();
265 Register right = comp->locs()->in(1).reg(); 265 Register right = comp->locs()->in(1).reg();
266 Register temp = comp->locs()->temp(0).reg(); 266 Register temp = comp->locs()->temp(0).reg();
267 Label* deopt = compiler->AddDeoptStub(comp->cid(), 267 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
268 comp->token_pos(), 268 comp->token_pos(),
269 comp->try_index(), 269 comp->try_index(),
270 kDeoptSmiCompareSmi, 270 kDeoptSmiCompareSmi,
271 left, 271 left,
272 right); 272 right);
273 __ movl(temp, left); 273 __ movl(temp, left);
274 __ orl(temp, right); 274 __ orl(temp, right);
275 __ testl(temp, Immediate(kSmiTagMask)); 275 __ testl(temp, Immediate(kSmiTagMask));
276 __ j(NOT_ZERO, deopt); 276 __ j(NOT_ZERO, deopt);
277 __ cmpl(left, right); 277 __ cmpl(left, right);
278 Register result = comp->locs()->out().reg(); 278 Register result = comp->locs()->out().reg();
279 Label load_true, done; 279 Label load_true, done;
280 __ j(TokenKindToSmiCondition(comp->kind()), &load_true, Assembler::kNearJump); 280 __ j(TokenKindToSmiCondition(comp->kind()), &load_true, Assembler::kNearJump);
281 __ LoadObject(result, compiler->bool_false()); 281 __ LoadObject(result, compiler->bool_false());
282 __ jmp(&done, Assembler::kNearJump); 282 __ jmp(&done, Assembler::kNearJump);
283 __ Bind(&load_true); 283 __ Bind(&load_true);
284 __ LoadObject(result, compiler->bool_true()); 284 __ LoadObject(result, compiler->bool_true());
285 __ Bind(&done); 285 __ Bind(&done);
286 } 286 }
287 287
288 288
289 // TODO(srdjan): Add support for mixed Smi/Double equality 289 // TODO(srdjan): Add support for mixed Smi/Double equality
290 // (see LoadDoubleOrSmiToXmm). 290 // (see LoadDoubleOrSmiToXmm).
291 static void EmitDoubleEqualityCompare(FlowGraphCompiler* compiler, 291 static void EmitDoubleEqualityCompare(FlowGraphCompiler* compiler,
292 EqualityCompareComp* comp) { 292 EqualityCompareComp* comp) {
293 Register left = comp->locs()->in(0).reg(); 293 Register left = comp->locs()->in(0).reg();
294 Register right = comp->locs()->in(1).reg(); 294 Register right = comp->locs()->in(1).reg();
295 Register temp = comp->locs()->temp(0).reg(); 295 Register temp = comp->locs()->temp(0).reg();
296 Label* deopt = compiler->AddDeoptStub(comp->cid(), 296 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
297 comp->token_pos(), 297 comp->token_pos(),
298 comp->try_index(), 298 comp->try_index(),
299 kDeoptDoubleCompareDouble, 299 kDeoptDoubleCompareDouble,
300 left, 300 left,
301 right); 301 right);
302 Label done, is_false, is_true; 302 Label done, is_false, is_true;
303 __ CompareClassId(left, kDouble, temp); 303 __ CompareClassId(left, kDouble, temp);
304 __ j(NOT_EQUAL, deopt); 304 __ j(NOT_EQUAL, deopt);
305 __ CompareClassId(right, kDouble, temp); 305 __ CompareClassId(right, kDouble, temp);
306 __ j(NOT_EQUAL, deopt); 306 __ j(NOT_EQUAL, deopt);
307 __ movsd(XMM0, FieldAddress(left, Double::value_offset())); 307 __ movsd(XMM0, FieldAddress(left, Double::value_offset()));
308 __ movsd(XMM1, FieldAddress(right, Double::value_offset())); 308 __ movsd(XMM1, FieldAddress(right, Double::value_offset()));
309 compiler->EmitDoubleCompareBool(TokenKindToSmiCondition(comp->kind()), 309 compiler->EmitDoubleCompareBool(TokenKindToSmiCondition(comp->kind()),
310 XMM0, XMM1, 310 XMM0, XMM1,
311 comp->locs()->out().reg()); 311 comp->locs()->out().reg());
312 } 312 }
313 313
314 314
315 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 315 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
316 EqualityCompareComp* comp) { 316 EqualityCompareComp* comp) {
317 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 317 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
318 comp->cid(), 318 comp->deopt_id(),
319 comp->token_pos(), 319 comp->token_pos(),
320 comp->try_index()); 320 comp->try_index());
321 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 321 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
322 const int kNumberOfArguments = 2; 322 const int kNumberOfArguments = 2;
323 const Array& kNoArgumentNames = Array::Handle(); 323 const Array& kNoArgumentNames = Array::Handle();
324 const int kNumArgumentsChecked = 2; 324 const int kNumArgumentsChecked = 2;
325 325
326 compiler->GenerateInstanceCall(comp->cid(), 326 compiler->GenerateInstanceCall(comp->deopt_id(),
327 comp->token_pos(), 327 comp->token_pos(),
328 comp->try_index(), 328 comp->try_index(),
329 operator_name, 329 operator_name,
330 kNumberOfArguments, 330 kNumberOfArguments,
331 kNoArgumentNames, 331 kNoArgumentNames,
332 kNumArgumentsChecked); 332 kNumArgumentsChecked);
333 ASSERT(comp->locs()->out().reg() == EAX); 333 ASSERT(comp->locs()->out().reg() == EAX);
334 if (comp->kind() == Token::kNE) { 334 if (comp->kind() == Token::kNE) {
335 Label done, false_label; 335 Label done, false_label;
336 __ CompareObject(EAX, compiler->bool_true()); 336 __ CompareObject(EAX, compiler->bool_true());
337 __ j(EQUAL, &false_label, Assembler::kNearJump); 337 __ j(EQUAL, &false_label, Assembler::kNearJump);
338 __ LoadObject(EAX, compiler->bool_true()); 338 __ LoadObject(EAX, compiler->bool_true());
339 __ jmp(&done, Assembler::kNearJump); 339 __ jmp(&done, Assembler::kNearJump);
340 __ Bind(&false_label); 340 __ Bind(&false_label);
341 __ LoadObject(EAX, compiler->bool_false()); 341 __ LoadObject(EAX, compiler->bool_false());
342 __ Bind(&done); 342 __ Bind(&done);
343 } 343 }
344 } 344 }
345 345
346 346
347 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 347 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
348 const ICData& orig_ic_data, 348 const ICData& orig_ic_data,
349 const LocationSummary& locs, 349 const LocationSummary& locs,
350 BranchInstr* branch, 350 BranchInstr* branch,
351 Token::Kind kind, 351 Token::Kind kind,
352 intptr_t cid, 352 intptr_t deopt_id,
353 intptr_t token_pos, 353 intptr_t token_pos,
354 intptr_t try_index) { 354 intptr_t try_index) {
355 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 355 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
356 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); 356 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
357 ASSERT(ic_data.NumberOfChecks() > 0); 357 ASSERT(ic_data.NumberOfChecks() > 0);
358 ASSERT(ic_data.num_args_tested() == 1); 358 ASSERT(ic_data.num_args_tested() == 1);
359 Label* deopt = compiler->AddDeoptStub(cid, 359 Label* deopt = compiler->AddDeoptStub(deopt_id,
360 token_pos, 360 token_pos,
361 try_index, 361 try_index,
362 kDeoptEquality); 362 kDeoptEquality);
363 Register left = locs.in(0).reg(); 363 Register left = locs.in(0).reg();
364 Register right = locs.in(1).reg(); 364 Register right = locs.in(1).reg();
365 __ testl(left, Immediate(kSmiTagMask)); 365 __ testl(left, Immediate(kSmiTagMask));
366 Register temp = locs.temp(0).reg(); 366 Register temp = locs.temp(0).reg();
367 if (ic_data.GetReceiverClassIdAt(0) == kSmi) { 367 if (ic_data.GetReceiverClassIdAt(0) == kSmi) {
368 Label done, load_class_id; 368 Label done, load_class_id;
369 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 369 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
(...skipping 27 matching lines...) Expand all
397 Label load_true; 397 Label load_true;
398 __ j(cond, &load_true, Assembler::kNearJump); 398 __ j(cond, &load_true, Assembler::kNearJump);
399 __ LoadObject(result, compiler->bool_false()); 399 __ LoadObject(result, compiler->bool_false());
400 __ jmp(&done); 400 __ jmp(&done);
401 __ Bind(&load_true); 401 __ Bind(&load_true);
402 __ LoadObject(result, compiler->bool_true()); 402 __ LoadObject(result, compiler->bool_true());
403 } 403 }
404 } else { 404 } else {
405 const int kNumberOfArguments = 2; 405 const int kNumberOfArguments = 2;
406 const Array& kNoArgumentNames = Array::Handle(); 406 const Array& kNoArgumentNames = Array::Handle();
407 compiler->GenerateStaticCall(cid, 407 compiler->GenerateStaticCall(deopt_id,
408 token_pos, 408 token_pos,
409 try_index, 409 try_index,
410 target, 410 target,
411 kNumberOfArguments, 411 kNumberOfArguments,
412 kNoArgumentNames); 412 kNoArgumentNames);
413 if (branch == NULL) { 413 if (branch == NULL) {
414 if (kind == Token::kNE) { 414 if (kind == Token::kNE) {
415 Label false_label; 415 Label false_label;
416 __ CompareObject(EAX, compiler->bool_true()); 416 __ CompareObject(EAX, compiler->bool_true());
417 __ j(EQUAL, &false_label, Assembler::kNearJump); 417 __ j(EQUAL, &false_label, Assembler::kNearJump);
(...skipping 18 matching lines...) Expand all
436 436
437 437
438 // First test if receiver is NULL, in which case === is applied. 438 // First test if receiver is NULL, in which case === is applied.
439 // If type feedback was provided (lists of <class-id, target>), do a 439 // If type feedback was provided (lists of <class-id, target>), do a
440 // type by type check (either === or static call to the operator. 440 // type by type check (either === or static call to the operator.
441 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, 441 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
442 const LocationSummary& locs, 442 const LocationSummary& locs,
443 Token::Kind kind, 443 Token::Kind kind,
444 BranchInstr* branch, 444 BranchInstr* branch,
445 const ICData& ic_data, 445 const ICData& ic_data,
446 intptr_t cid, 446 intptr_t deopt_id,
447 intptr_t token_pos, 447 intptr_t token_pos,
448 intptr_t try_index) { 448 intptr_t try_index) {
449 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 449 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
450 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 450 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
451 Register left = locs.in(0).reg(); 451 Register left = locs.in(0).reg();
452 Register right = locs.in(1).reg(); 452 Register right = locs.in(1).reg();
453 const Immediate raw_null = 453 const Immediate raw_null =
454 Immediate(reinterpret_cast<intptr_t>(Object::null())); 454 Immediate(reinterpret_cast<intptr_t>(Object::null()));
455 Label done, non_null_compare; 455 Label done, non_null_compare;
456 __ cmpl(left, raw_null); 456 __ cmpl(left, raw_null);
(...skipping 10 matching lines...) Expand all
467 __ LoadObject(result, compiler->bool_false()); 467 __ LoadObject(result, compiler->bool_false());
468 __ jmp(&done); 468 __ jmp(&done);
469 __ Bind(&load_true); 469 __ Bind(&load_true);
470 __ LoadObject(result, compiler->bool_true()); 470 __ LoadObject(result, compiler->bool_true());
471 } 471 }
472 __ jmp(&done); 472 __ jmp(&done);
473 __ Bind(&non_null_compare); // Receiver is not null. 473 __ Bind(&non_null_compare); // Receiver is not null.
474 __ pushl(left); 474 __ pushl(left);
475 __ pushl(right); 475 __ pushl(right);
476 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 476 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
477 cid, token_pos, try_index); 477 deopt_id, token_pos, try_index);
478 __ Bind(&done); 478 __ Bind(&done);
479 } 479 }
480 480
481 481
482 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 482 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
483 if (receiver_class_id() == kSmi) { 483 if (receiver_class_id() == kSmi) {
484 EmitSmiEqualityCompare(compiler, this); 484 EmitSmiEqualityCompare(compiler, this);
485 return; 485 return;
486 } 486 }
487 if (receiver_class_id() == kDouble) { 487 if (receiver_class_id() == kDouble) {
488 EmitDoubleEqualityCompare(compiler, this); 488 EmitDoubleEqualityCompare(compiler, this);
489 return; 489 return;
490 } 490 }
491 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 491 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
492 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, 492 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
493 *ic_data(), cid(), token_pos(), try_index()); 493 deopt_id(), token_pos(), try_index());
494 } else { 494 } else {
495 Register left = locs()->in(0).reg(); 495 Register left = locs()->in(0).reg();
496 Register right = locs()->in(1).reg(); 496 Register right = locs()->in(1).reg();
497 __ pushl(left); 497 __ pushl(left);
498 __ pushl(right); 498 __ pushl(right);
499 EmitEqualityAsInstanceCall(compiler, this); 499 EmitEqualityAsInstanceCall(compiler, this);
500 } 500 }
501 } 501 }
502 502
503 503
(...skipping 11 matching lines...) Expand all
515 } 515 }
516 ASSERT(operands_class_id() == kObject); 516 ASSERT(operands_class_id() == kObject);
517 return MakeCallSummary(); 517 return MakeCallSummary();
518 } 518 }
519 519
520 520
521 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 521 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
522 const LocationSummary& locs, 522 const LocationSummary& locs,
523 Token::Kind kind, 523 Token::Kind kind,
524 BranchInstr* branch, 524 BranchInstr* branch,
525 intptr_t cid, 525 intptr_t deopt_id,
526 intptr_t token_pos, 526 intptr_t token_pos,
527 intptr_t try_index) { 527 intptr_t try_index) {
528 Register left = locs.in(0).reg(); 528 Register left = locs.in(0).reg();
529 Register right = locs.in(1).reg(); 529 Register right = locs.in(1).reg();
530 Register temp = locs.temp(0).reg(); 530 Register temp = locs.temp(0).reg();
531 Label* deopt = compiler->AddDeoptStub(cid, 531 Label* deopt = compiler->AddDeoptStub(deopt_id,
532 token_pos, 532 token_pos,
533 try_index, 533 try_index,
534 kDeoptSmiCompareSmi, 534 kDeoptSmiCompareSmi,
535 left, 535 left,
536 right); 536 right);
537 __ movl(temp, left); 537 __ movl(temp, left);
538 __ orl(temp, right); 538 __ orl(temp, right);
539 __ testl(temp, Immediate(kSmiTagMask)); 539 __ testl(temp, Immediate(kSmiTagMask));
540 __ j(NOT_ZERO, deopt); 540 __ j(NOT_ZERO, deopt);
541 541
(...skipping 27 matching lines...) Expand all
569 UNREACHABLE(); 569 UNREACHABLE();
570 return OVERFLOW; 570 return OVERFLOW;
571 } 571 }
572 } 572 }
573 573
574 574
575 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler, 575 static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
576 const LocationSummary& locs, 576 const LocationSummary& locs,
577 Token::Kind kind, 577 Token::Kind kind,
578 BranchInstr* branch, 578 BranchInstr* branch,
579 intptr_t cid, 579 intptr_t deopt_id,
580 intptr_t token_pos, 580 intptr_t token_pos,
581 intptr_t try_index) { 581 intptr_t try_index) {
582 Register left = locs.in(0).reg(); 582 Register left = locs.in(0).reg();
583 Register right = locs.in(1).reg(); 583 Register right = locs.in(1).reg();
584 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs. 584 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
585 Register temp = locs.temp(0).reg(); 585 Register temp = locs.temp(0).reg();
586 Label* deopt = compiler->AddDeoptStub(cid, 586 Label* deopt = compiler->AddDeoptStub(deopt_id,
587 token_pos, 587 token_pos,
588 try_index, 588 try_index,
589 kDeoptDoubleComparison, 589 kDeoptDoubleComparison,
590 left, 590 left,
591 right); 591 right);
592 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); 592 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
593 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); 593 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
594 594
595 Condition true_condition = TokenKindToDoubleCondition(kind); 595 Condition true_condition = TokenKindToDoubleCondition(kind);
596 if (branch != NULL) { 596 if (branch != NULL) {
597 compiler->EmitDoubleCompareBranch( 597 compiler->EmitDoubleCompareBranch(
598 true_condition, XMM0, XMM1, branch); 598 true_condition, XMM0, XMM1, branch);
599 } else { 599 } else {
600 compiler->EmitDoubleCompareBool( 600 compiler->EmitDoubleCompareBool(
601 true_condition, XMM0, XMM1, locs.out().reg()); 601 true_condition, XMM0, XMM1, locs.out().reg());
602 } 602 }
603 } 603 }
604 604
605 605
606 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 606 void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
607 if (operands_class_id() == kSmi) { 607 if (operands_class_id() == kSmi) {
608 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, 608 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL,
609 cid(), token_pos(), try_index()); 609 deopt_id(), token_pos(), try_index());
610 return; 610 return;
611 } 611 }
612 if (operands_class_id() == kDouble) { 612 if (operands_class_id() == kDouble) {
613 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, 613 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL,
614 cid(), token_pos(), try_index()); 614 deopt_id(), token_pos(), try_index());
615 return; 615 return;
616 } 616 }
617 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 617 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
618 Label* deopt = compiler->AddDeoptStub(cid(), 618 Label* deopt = compiler->AddDeoptStub(deopt_id(),
619 token_pos(), 619 token_pos(),
620 try_index(), 620 try_index(),
621 kDeoptRelationalOp); 621 kDeoptRelationalOp);
622 // Load receiver into EAX, class into EDI. 622 // Load receiver into EAX, class into EDI.
623 Label done; 623 Label done;
624 const intptr_t kNumArguments = 2; 624 const intptr_t kNumArguments = 2;
625 __ movl(EDI, Immediate(kSmi)); 625 __ movl(EDI, Immediate(kSmi));
626 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); 626 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
627 __ testl(EAX, Immediate(kSmiTagMask)); 627 __ testl(EAX, Immediate(kSmiTagMask));
628 __ j(ZERO, &done); 628 __ j(ZERO, &done);
629 __ LoadClassId(EDI, EAX); 629 __ LoadClassId(EDI, EAX);
630 __ Bind(&done); 630 __ Bind(&done);
631 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), 631 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
632 EDI, // Class id register. 632 EDI, // Class id register.
633 kNumArguments, 633 kNumArguments,
634 Array::Handle(), // No named arguments. 634 Array::Handle(), // No named arguments.
635 deopt, // Deoptimize target. 635 deopt, // Deoptimize target.
636 NULL, // Fallthrough when done. 636 NULL, // Fallthrough when done.
637 cid(), 637 deopt_id(),
638 token_pos(), 638 token_pos(),
639 try_index()); 639 try_index());
640 return; 640 return;
641 } 641 }
642 const String& function_name = 642 const String& function_name =
643 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 643 String::ZoneHandle(Symbols::New(Token::Str(kind())));
644 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 644 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
645 cid(), 645 deopt_id(),
646 token_pos(), 646 token_pos(),
647 try_index()); 647 try_index());
648 const intptr_t kNumArguments = 2; 648 const intptr_t kNumArguments = 2;
649 const intptr_t kNumArgsChecked = 2; // Type-feedback. 649 const intptr_t kNumArgsChecked = 2; // Type-feedback.
650 compiler->GenerateInstanceCall(cid(), 650 compiler->GenerateInstanceCall(deopt_id(),
651 token_pos(), 651 token_pos(),
652 try_index(), 652 try_index(),
653 function_name, 653 function_name,
654 kNumArguments, 654 kNumArguments,
655 Array::ZoneHandle(), // No optional arguments. 655 Array::ZoneHandle(), // No optional arguments.
656 kNumArgsChecked); 656 kNumArgsChecked);
657 ASSERT(locs()->out().reg() == EAX); 657 ASSERT(locs()->out().reg() == EAX);
658 } 658 }
659 659
660 660
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 return locs; 715 return locs;
716 } else { 716 } else {
717 ASSERT(receiver_type() == kIllegalObjectKind); 717 ASSERT(receiver_type() == kIllegalObjectKind);
718 return MakeCallSummary(); 718 return MakeCallSummary();
719 } 719 }
720 } 720 }
721 721
722 722
723 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, 723 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
724 LoadIndexedComp* comp) { 724 LoadIndexedComp* comp) {
725 Label* deopt = compiler->AddDeoptStub(comp->cid(), 725 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
726 comp->token_pos(), 726 comp->token_pos(),
727 comp->try_index(), 727 comp->try_index(),
728 kDeoptLoadIndexedPolymorphic); 728 kDeoptLoadIndexedPolymorphic);
729 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 729 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
730 ASSERT(comp->HasICData()); 730 ASSERT(comp->HasICData());
731 const ICData& ic_data = *comp->ic_data(); 731 const ICData& ic_data = *comp->ic_data();
732 ASSERT(ic_data.num_args_tested() == 1); 732 ASSERT(ic_data.num_args_tested() == 1);
733 // No indexed access on Smi. 733 // No indexed access on Smi.
734 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); 734 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
735 // Load receiver into EAX. 735 // Load receiver into EAX.
736 const intptr_t kNumArguments = 2; 736 const intptr_t kNumArguments = 2;
737 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); 737 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
738 __ testl(EAX, Immediate(kSmiTagMask)); 738 __ testl(EAX, Immediate(kSmiTagMask));
739 __ j(ZERO, deopt); 739 __ j(ZERO, deopt);
740 __ LoadClassId(EDI, EAX); 740 __ LoadClassId(EDI, EAX);
741 compiler->EmitTestAndCall(ic_data, 741 compiler->EmitTestAndCall(ic_data,
742 EDI, // Class id register. 742 EDI, // Class id register.
743 kNumArguments, 743 kNumArguments,
744 Array::Handle(), // No named arguments. 744 Array::Handle(), // No named arguments.
745 deopt, // Deoptimize target. 745 deopt, // Deoptimize target.
746 NULL, // Fallthrough when done. 746 NULL, // Fallthrough when done.
747 comp->cid(), 747 comp->deopt_id(),
748 comp->token_pos(), 748 comp->token_pos(),
749 comp->try_index()); 749 comp->try_index());
750 } 750 }
751 751
752 752
753 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 753 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
754 if (receiver_type() == kIllegalObjectKind) { 754 if (receiver_type() == kIllegalObjectKind) {
755 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 755 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
756 EmitLoadIndexedPolymorphic(compiler, this); 756 EmitLoadIndexedPolymorphic(compiler, this);
757 } else { 757 } else {
758 compiler->EmitLoadIndexedGeneric(this); 758 compiler->EmitLoadIndexedGeneric(this);
759 } 759 }
760 ASSERT(locs()->out().reg() == EAX); 760 ASSERT(locs()->out().reg() == EAX);
761 return; 761 return;
762 } 762 }
763 763
764 Register receiver = locs()->in(0).reg(); 764 Register receiver = locs()->in(0).reg();
765 Register index = locs()->in(1).reg(); 765 Register index = locs()->in(1).reg();
766 Register result = locs()->out().reg(); 766 Register result = locs()->out().reg();
767 Register temp = locs()->temp(0).reg(); 767 Register temp = locs()->temp(0).reg();
768 768
769 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ? 769 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ?
770 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 770 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
771 771
772 Label* deopt = compiler->AddDeoptStub(cid(), 772 Label* deopt = compiler->AddDeoptStub(deopt_id(),
773 token_pos(), 773 token_pos(),
774 try_index(), 774 try_index(),
775 deopt_reason, 775 deopt_reason,
776 receiver, 776 receiver,
777 index); 777 index);
778 778
779 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 779 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
780 __ j(ZERO, deopt); 780 __ j(ZERO, deopt);
781 __ CompareClassId(receiver, receiver_type(), temp); 781 __ CompareClassId(receiver, receiver_type(), temp);
782 __ j(NOT_EQUAL, deopt); 782 __ j(NOT_EQUAL, deopt);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 } 833 }
834 } 834 }
835 835
836 836
837 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, 837 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler,
838 StoreIndexedComp* comp) { 838 StoreIndexedComp* comp) {
839 const String& function_name = 839 const String& function_name =
840 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); 840 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
841 841
842 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 842 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
843 comp->cid(), 843 comp->deopt_id(),
844 comp->token_pos(), 844 comp->token_pos(),
845 comp->try_index()); 845 comp->try_index());
846 846
847 const intptr_t kNumArguments = 3; 847 const intptr_t kNumArguments = 3;
848 const intptr_t kNumArgsChecked = 1; // Type-feedback. 848 const intptr_t kNumArgsChecked = 1; // Type-feedback.
849 compiler->GenerateInstanceCall(comp->cid(), 849 compiler->GenerateInstanceCall(comp->deopt_id(),
850 comp->token_pos(), 850 comp->token_pos(),
851 comp->try_index(), 851 comp->try_index(),
852 function_name, 852 function_name,
853 kNumArguments, 853 kNumArguments,
854 Array::ZoneHandle(), // No named arguments. 854 Array::ZoneHandle(), // No named arguments.
855 kNumArgsChecked); 855 kNumArgsChecked);
856 } 856 }
857 857
858 858
859 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, 859 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler,
860 StoreIndexedComp* comp) { 860 StoreIndexedComp* comp) {
861 Label* deopt = compiler->AddDeoptStub(comp->cid(), 861 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
862 comp->token_pos(), 862 comp->token_pos(),
863 comp->try_index(), 863 comp->try_index(),
864 kDeoptStoreIndexedPolymorphic); 864 kDeoptStoreIndexedPolymorphic);
865 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 865 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
866 ASSERT(comp->HasICData()); 866 ASSERT(comp->HasICData());
867 const ICData& ic_data = *comp->ic_data(); 867 const ICData& ic_data = *comp->ic_data();
868 ASSERT(ic_data.num_args_tested() == 1); 868 ASSERT(ic_data.num_args_tested() == 1);
869 // No indexed access on Smi. 869 // No indexed access on Smi.
870 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); 870 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
871 // Load receiver into EAX. 871 // Load receiver into EAX.
872 const intptr_t kNumArguments = 3; 872 const intptr_t kNumArguments = 3;
873 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); 873 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
874 __ testl(EAX, Immediate(kSmiTagMask)); 874 __ testl(EAX, Immediate(kSmiTagMask));
875 __ j(ZERO, deopt); 875 __ j(ZERO, deopt);
876 __ LoadClassId(EDI, EAX); 876 __ LoadClassId(EDI, EAX);
877 compiler->EmitTestAndCall(ic_data, 877 compiler->EmitTestAndCall(ic_data,
878 EDI, // Class id register. 878 EDI, // Class id register.
879 kNumArguments, 879 kNumArguments,
880 Array::Handle(), // No named arguments. 880 Array::Handle(), // No named arguments.
881 deopt, // Deoptimize target. 881 deopt, // Deoptimize target.
882 NULL, // Fallthrough when done. 882 NULL, // Fallthrough when done.
883 comp->cid(), 883 comp->deopt_id(),
884 comp->token_pos(), 884 comp->token_pos(),
885 comp->try_index()); 885 comp->try_index());
886 } 886 }
887 887
888 888
889 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 889 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
890 if (receiver_type() == kIllegalObjectKind) { 890 if (receiver_type() == kIllegalObjectKind) {
891 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 891 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
892 EmitStoreIndexedPolymorphic(compiler, this); 892 EmitStoreIndexedPolymorphic(compiler, this);
893 } else { 893 } else {
894 EmitStoreIndexedGeneric(compiler, this); 894 EmitStoreIndexedGeneric(compiler, this);
895 } 895 }
896 return; 896 return;
897 } 897 }
898 898
899 Register receiver = locs()->in(0).reg(); 899 Register receiver = locs()->in(0).reg();
900 Register index = locs()->in(1).reg(); 900 Register index = locs()->in(1).reg();
901 Register value = locs()->in(2).reg(); 901 Register value = locs()->in(2).reg();
902 Register temp = locs()->temp(0).reg(); 902 Register temp = locs()->temp(0).reg();
903 903
904 Label* deopt = compiler->AddDeoptStub(cid(), 904 Label* deopt = compiler->AddDeoptStub(deopt_id(),
905 token_pos(), 905 token_pos(),
906 try_index(), 906 try_index(),
907 kDeoptStoreIndexed, 907 kDeoptStoreIndexed,
908 receiver, 908 receiver,
909 index, 909 index,
910 value); 910 value);
911 911
912 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 912 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
913 __ j(ZERO, deopt); 913 __ j(ZERO, deopt);
914 __ CompareClassId(receiver, receiver_type(), temp); 914 __ CompareClassId(receiver, receiver_type(), temp);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 LocationSummary::kNoCall); 959 LocationSummary::kNoCall);
960 } 960 }
961 961
962 962
963 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 963 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
964 Register instance_reg = locs()->in(0).reg(); 964 Register instance_reg = locs()->in(0).reg();
965 Register result_reg = locs()->out().reg(); 965 Register result_reg = locs()->out().reg();
966 966
967 if (HasICData()) { 967 if (HasICData()) {
968 ASSERT(original() != NULL); 968 ASSERT(original() != NULL);
969 Label* deopt = compiler->AddDeoptStub(original()->cid(), 969 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(),
970 original()->token_pos(), 970 original()->token_pos(),
971 original()->try_index(), 971 original()->try_index(),
972 kDeoptInstanceGetterSameTarget, 972 kDeoptInstanceGetterSameTarget,
973 instance_reg); 973 instance_reg);
974 // Smis do not have instance fields (Smi class is always first). 974 // Smis do not have instance fields (Smi class is always first).
975 // Use 'result' as temporary register. 975 // Use 'result' as temporary register.
976 ASSERT(result_reg != instance_reg); 976 ASSERT(result_reg != instance_reg);
977 ASSERT(ic_data() != NULL); 977 ASSERT(ic_data() != NULL);
978 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); 978 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
979 } 979 }
(...skipping 26 matching lines...) Expand all
1006 summary->set_out(Location::RegisterLocation(EAX)); 1006 summary->set_out(Location::RegisterLocation(EAX));
1007 return summary; 1007 return summary;
1008 } 1008 }
1009 1009
1010 1010
1011 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1011 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1012 ASSERT(locs()->in(0).reg() == EAX); // Value. 1012 ASSERT(locs()->in(0).reg() == EAX); // Value.
1013 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. 1013 ASSERT(locs()->in(1).reg() == ECX); // Instantiator.
1014 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. 1014 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments.
1015 1015
1016 compiler->GenerateInstanceOf(cid(), 1016 compiler->GenerateInstanceOf(deopt_id(),
1017 token_pos(), 1017 token_pos(),
1018 try_index(), 1018 try_index(),
1019 type(), 1019 type(),
1020 negate_result()); 1020 negate_result());
1021 ASSERT(locs()->out().reg() == EAX); 1021 ASSERT(locs()->out().reg() == EAX);
1022 } 1022 }
1023 1023
1024 1024
1025 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 1025 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
1026 return MakeCallSummary(); 1026 return MakeCallSummary();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 const Class& cls = Class::ZoneHandle(constructor().owner()); 1065 const Class& cls = Class::ZoneHandle(constructor().owner());
1066 Register type_arguments = locs()->in(0).reg(); 1066 Register type_arguments = locs()->in(0).reg();
1067 Register instantiator_type_arguments = locs()->in(1).reg(); 1067 Register instantiator_type_arguments = locs()->in(1).reg();
1068 Register result = locs()->out().reg(); 1068 Register result = locs()->out().reg();
1069 1069
1070 // Push the result place holder initialized to NULL. 1070 // Push the result place holder initialized to NULL.
1071 __ PushObject(Object::ZoneHandle()); 1071 __ PushObject(Object::ZoneHandle());
1072 __ PushObject(cls); 1072 __ PushObject(cls);
1073 __ pushl(type_arguments); 1073 __ pushl(type_arguments);
1074 __ pushl(instantiator_type_arguments); 1074 __ pushl(instantiator_type_arguments);
1075 compiler->GenerateCallRuntime(cid(), 1075 compiler->GenerateCallRuntime(deopt_id(),
1076 token_pos(), 1076 token_pos(),
1077 try_index(), 1077 try_index(),
1078 kAllocateObjectWithBoundsCheckRuntimeEntry); 1078 kAllocateObjectWithBoundsCheckRuntimeEntry);
1079 // Pop instantiator type arguments, type arguments, and class. 1079 // Pop instantiator type arguments, type arguments, and class.
1080 // source location. 1080 // source location.
1081 __ Drop(3); 1081 __ Drop(3);
1082 __ popl(result); // Pop new instance. 1082 __ popl(result); // Pop new instance.
1083 } 1083 }
1084 1084
1085 1085
1086 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 1086 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
1087 return LocationSummary::Make(1, 1087 return LocationSummary::Make(1,
1088 Location::RequiresRegister(), 1088 Location::RequiresRegister(),
1089 LocationSummary::kNoCall); 1089 LocationSummary::kNoCall);
1090 } 1090 }
1091 1091
1092 1092
1093 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1093 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1094 Register instance_reg = locs()->in(0).reg(); 1094 Register instance_reg = locs()->in(0).reg();
1095 Register result_reg = locs()->out().reg(); 1095 Register result_reg = locs()->out().reg();
1096 if (HasICData()) { 1096 if (HasICData()) {
1097 ASSERT(original() != NULL); 1097 ASSERT(original() != NULL);
1098 Label* deopt = compiler->AddDeoptStub(original()->cid(), 1098 Label* deopt = compiler->AddDeoptStub(original()->deopt_id(),
1099 original()->token_pos(), 1099 original()->token_pos(),
1100 original()->try_index(), 1100 original()->try_index(),
1101 kDeoptInstanceGetterSameTarget, 1101 kDeoptInstanceGetterSameTarget,
1102 instance_reg); 1102 instance_reg);
1103 // Smis do not have instance fields (Smi class is always first). 1103 // Smis do not have instance fields (Smi class is always first).
1104 // Use 'result' as temporary register. 1104 // Use 'result' as temporary register.
1105 ASSERT(result_reg != instance_reg); 1105 ASSERT(result_reg != instance_reg);
1106 ASSERT(ic_data() != NULL); 1106 ASSERT(ic_data() != NULL);
1107 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); 1107 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
1108 } 1108 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump); 1154 __ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
1155 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 1155 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1156 Immediate(Smi::RawValue(len))); 1156 Immediate(Smi::RawValue(len)));
1157 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1157 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1158 __ Bind(&type_arguments_uninstantiated); 1158 __ Bind(&type_arguments_uninstantiated);
1159 } 1159 }
1160 // A runtime call to instantiate the type arguments is required. 1160 // A runtime call to instantiate the type arguments is required.
1161 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1161 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1162 __ PushObject(type_arguments()); 1162 __ PushObject(type_arguments());
1163 __ pushl(instantiator_reg); // Push instantiator type arguments. 1163 __ pushl(instantiator_reg); // Push instantiator type arguments.
1164 compiler->GenerateCallRuntime(cid(), 1164 compiler->GenerateCallRuntime(deopt_id(),
1165 token_pos(), 1165 token_pos(),
1166 try_index(), 1166 try_index(),
1167 kInstantiateTypeArgumentsRuntimeEntry); 1167 kInstantiateTypeArgumentsRuntimeEntry);
1168 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1168 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1169 __ popl(result_reg); // Pop instantiated type arguments. 1169 __ popl(result_reg); // Pop instantiated type arguments.
1170 __ Bind(&type_arguments_instantiated); 1170 __ Bind(&type_arguments_instantiated);
1171 ASSERT(instantiator_reg == result_reg); 1171 ASSERT(instantiator_reg == result_reg);
1172 // 'result_reg': Instantiated type arguments. 1172 // 'result_reg': Instantiated type arguments.
1173 } 1173 }
1174 1174
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 return locs; 1334 return locs;
1335 } 1335 }
1336 1336
1337 1337
1338 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1338 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1339 Register context_value = locs()->in(0).reg(); 1339 Register context_value = locs()->in(0).reg();
1340 Register result = locs()->out().reg(); 1340 Register result = locs()->out().reg();
1341 1341
1342 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1342 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1343 __ pushl(context_value); 1343 __ pushl(context_value);
1344 compiler->GenerateCallRuntime(cid(), 1344 compiler->GenerateCallRuntime(deopt_id(),
1345 token_pos(), 1345 token_pos(),
1346 try_index(), 1346 try_index(),
1347 kCloneContextRuntimeEntry); 1347 kCloneContextRuntimeEntry);
1348 __ popl(result); // Remove argument. 1348 __ popl(result); // Remove argument.
1349 __ popl(result); // Get result (cloned context). 1349 __ popl(result); // Get result (cloned context).
1350 } 1350 }
1351 1351
1352 1352
1353 LocationSummary* CatchEntryComp::MakeLocationSummary() const { 1353 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
1354 return LocationSummary::Make(0, 1354 return LocationSummary::Make(0,
(...skipping 30 matching lines...) Expand all
1385 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1385 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1386 return summary; 1386 return summary;
1387 } 1387 }
1388 1388
1389 1389
1390 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1390 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1391 __ cmpl(ESP, 1391 __ cmpl(ESP,
1392 Address::Absolute(Isolate::Current()->stack_limit_address())); 1392 Address::Absolute(Isolate::Current()->stack_limit_address()));
1393 Label no_stack_overflow; 1393 Label no_stack_overflow;
1394 __ j(ABOVE, &no_stack_overflow); 1394 __ j(ABOVE, &no_stack_overflow);
1395 compiler->GenerateCallRuntime(cid(), 1395 compiler->GenerateCallRuntime(deopt_id(),
1396 token_pos(), 1396 token_pos(),
1397 try_index(), 1397 try_index(),
1398 kStackOverflowRuntimeEntry); 1398 kStackOverflowRuntimeEntry);
1399 __ Bind(&no_stack_overflow); 1399 __ Bind(&no_stack_overflow);
1400 } 1400 }
1401 1401
1402 1402
1403 LocationSummary* BinaryOpComp::MakeLocationSummary() const { 1403 LocationSummary* BinaryOpComp::MakeLocationSummary() const {
1404 const intptr_t kNumInputs = 2; 1404 const intptr_t kNumInputs = 2;
1405 1405
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1464 } 1464 }
1465 } 1465 }
1466 1466
1467 1467
1468 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { 1468 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) {
1469 Register left = comp->locs()->in(0).reg(); 1469 Register left = comp->locs()->in(0).reg();
1470 Register right = comp->locs()->in(1).reg(); 1470 Register right = comp->locs()->in(1).reg();
1471 Register result = comp->locs()->out().reg(); 1471 Register result = comp->locs()->out().reg();
1472 Register temp = comp->locs()->temp(0).reg(); 1472 Register temp = comp->locs()->temp(0).reg();
1473 ASSERT(left == result); 1473 ASSERT(left == result);
1474 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), 1474 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(),
1475 comp->instance_call()->token_pos(), 1475 comp->instance_call()->token_pos(),
1476 comp->instance_call()->try_index(), 1476 comp->instance_call()->try_index(),
1477 kDeoptSmiBinaryOp, 1477 kDeoptSmiBinaryOp,
1478 temp, 1478 temp,
1479 right); 1479 right);
1480 // TODO(vegorov): for many binary operations this pattern can be rearranged 1480 // TODO(vegorov): for many binary operations this pattern can be rearranged
1481 // to save one move. 1481 // to save one move.
1482 __ movl(temp, left); 1482 __ movl(temp, left);
1483 __ orl(left, right); 1483 __ orl(left, right);
1484 __ testl(left, Immediate(kSmiTagMask)); 1484 __ testl(left, Immediate(kSmiTagMask));
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 __ shll(left, right_temp); 1575 __ shll(left, right_temp);
1576 __ jmp(&done); 1576 __ jmp(&done);
1577 { 1577 {
1578 __ Bind(&call_method); 1578 __ Bind(&call_method);
1579 Function& target = Function::ZoneHandle( 1579 Function& target = Function::ZoneHandle(
1580 comp->ic_data()->GetTargetForReceiverClassId(kSmi)); 1580 comp->ic_data()->GetTargetForReceiverClassId(kSmi));
1581 ASSERT(!target.IsNull()); 1581 ASSERT(!target.IsNull());
1582 const intptr_t kArgumentCount = 2; 1582 const intptr_t kArgumentCount = 2;
1583 __ pushl(temp); 1583 __ pushl(temp);
1584 __ pushl(right); 1584 __ pushl(right);
1585 compiler->GenerateStaticCall(comp->instance_call()->cid(), 1585 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(),
1586 comp->instance_call()->token_pos(), 1586 comp->instance_call()->token_pos(),
1587 comp->instance_call()->try_index(), 1587 comp->instance_call()->try_index(),
1588 target, 1588 target,
1589 kArgumentCount, 1589 kArgumentCount,
1590 Array::Handle()); // No argument names. 1590 Array::Handle()); // No argument names.
1591 ASSERT(result == EAX); 1591 ASSERT(result == EAX);
1592 } 1592 }
1593 __ Bind(&done); 1593 __ Bind(&done);
1594 break; 1594 break;
1595 } 1595 }
(...skipping 26 matching lines...) Expand all
1622 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi 1622 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi
1623 // receiver and a Mint or Smi argument. We fall back to the run time call if 1623 // receiver and a Mint or Smi argument. We fall back to the run time call if
1624 // both receiver and argument are Mint or if one of them is Mint and the other 1624 // both receiver and argument are Mint or if one of them is Mint and the other
1625 // is a negative Smi. 1625 // is a negative Smi.
1626 Register left = comp->locs()->in(0).reg(); 1626 Register left = comp->locs()->in(0).reg();
1627 Register right = comp->locs()->in(1).reg(); 1627 Register right = comp->locs()->in(1).reg();
1628 Register result = comp->locs()->out().reg(); 1628 Register result = comp->locs()->out().reg();
1629 Register temp = comp->locs()->temp(0).reg(); 1629 Register temp = comp->locs()->temp(0).reg();
1630 ASSERT(left == result); 1630 ASSERT(left == result);
1631 ASSERT(comp->op_kind() == Token::kBIT_AND); 1631 ASSERT(comp->op_kind() == Token::kBIT_AND);
1632 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), 1632 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(),
1633 comp->instance_call()->token_pos(), 1633 comp->instance_call()->token_pos(),
1634 comp->instance_call()->try_index(), 1634 comp->instance_call()->try_index(),
1635 kDeoptMintBinaryOp, 1635 kDeoptMintBinaryOp,
1636 left, 1636 left,
1637 right); 1637 right);
1638 Label mint_static_call, smi_static_call, non_smi, smi_smi, done; 1638 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1639 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi? 1639 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1640 __ j(NOT_ZERO, &non_smi); 1640 __ j(NOT_ZERO, &non_smi);
1641 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi? 1641 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi?
1642 __ j(ZERO, &smi_smi); 1642 __ j(ZERO, &smi_smi);
(...skipping 27 matching lines...) Expand all
1670 1670
1671 __ Bind(&smi_static_call); 1671 __ Bind(&smi_static_call);
1672 { 1672 {
1673 Function& target = Function::ZoneHandle( 1673 Function& target = Function::ZoneHandle(
1674 comp->ic_data()->GetTargetForReceiverClassId(kSmi)); 1674 comp->ic_data()->GetTargetForReceiverClassId(kSmi));
1675 if (target.IsNull()) { 1675 if (target.IsNull()) {
1676 __ jmp(deopt); 1676 __ jmp(deopt);
1677 } else { 1677 } else {
1678 __ pushl(left); 1678 __ pushl(left);
1679 __ pushl(right); 1679 __ pushl(right);
1680 compiler->GenerateStaticCall(comp->instance_call()->cid(), 1680 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(),
1681 comp->instance_call()->token_pos(), 1681 comp->instance_call()->token_pos(),
1682 comp->instance_call()->try_index(), 1682 comp->instance_call()->try_index(),
1683 target, 1683 target,
1684 comp->instance_call()->ArgumentCount(), 1684 comp->instance_call()->ArgumentCount(),
1685 comp->instance_call()->argument_names()); 1685 comp->instance_call()->argument_names());
1686 ASSERT(result == EAX); 1686 ASSERT(result == EAX);
1687 __ jmp(&done); 1687 __ jmp(&done);
1688 } 1688 }
1689 } 1689 }
1690 1690
1691 __ Bind(&mint_static_call); 1691 __ Bind(&mint_static_call);
1692 { 1692 {
1693 Function& target = Function::ZoneHandle( 1693 Function& target = Function::ZoneHandle(
1694 comp->ic_data()->GetTargetForReceiverClassId(kMint)); 1694 comp->ic_data()->GetTargetForReceiverClassId(kMint));
1695 if (target.IsNull()) { 1695 if (target.IsNull()) {
1696 __ jmp(deopt); 1696 __ jmp(deopt);
1697 } else { 1697 } else {
1698 __ pushl(left); 1698 __ pushl(left);
1699 __ pushl(right); 1699 __ pushl(right);
1700 compiler->GenerateStaticCall(comp->instance_call()->cid(), 1700 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(),
1701 comp->instance_call()->token_pos(), 1701 comp->instance_call()->token_pos(),
1702 comp->instance_call()->try_index(), 1702 comp->instance_call()->try_index(),
1703 target, 1703 target,
1704 comp->instance_call()->ArgumentCount(), 1704 comp->instance_call()->ArgumentCount(),
1705 comp->instance_call()->argument_names()); 1705 comp->instance_call()->argument_names());
1706 ASSERT(result == EAX); 1706 ASSERT(result == EAX);
1707 } 1707 }
1708 } 1708 }
1709 __ Bind(&done); 1709 __ Bind(&done);
1710 } 1710 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1743 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1744 compiler->GenerateCall(instance_call()->token_pos(), 1744 compiler->GenerateCall(instance_call()->token_pos(),
1745 instance_call()->try_index(), 1745 instance_call()->try_index(),
1746 &label, 1746 &label,
1747 PcDescriptors::kOther); 1747 PcDescriptors::kOther);
1748 // Newly allocated object is now in the result register (RAX). 1748 // Newly allocated object is now in the result register (RAX).
1749 ASSERT(result == EAX); 1749 ASSERT(result == EAX);
1750 __ popl(right); 1750 __ popl(right);
1751 __ popl(left); 1751 __ popl(left);
1752 1752
1753 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1753 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1754 instance_call()->token_pos(), 1754 instance_call()->token_pos(),
1755 instance_call()->try_index(), 1755 instance_call()->try_index(),
1756 kDeoptDoubleBinaryOp, 1756 kDeoptDoubleBinaryOp,
1757 left, 1757 left,
1758 right); 1758 right);
1759 1759
1760 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); 1760 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
1761 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); 1761 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
1762 1762
1763 switch (op_kind()) { 1763 switch (op_kind()) {
(...skipping 25 matching lines...) Expand all
1789 ASSERT(ic_data.num_args_tested() == 1); 1789 ASSERT(ic_data.num_args_tested() == 1);
1790 // TODO(srdjan): Implement for more checks. 1790 // TODO(srdjan): Implement for more checks.
1791 ASSERT(ic_data.NumberOfChecks() == 1); 1791 ASSERT(ic_data.NumberOfChecks() == 1);
1792 intptr_t test_class_id; 1792 intptr_t test_class_id;
1793 Function& target = Function::Handle(); 1793 Function& target = Function::Handle();
1794 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1794 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1795 1795
1796 Register value = locs()->in(0).reg(); 1796 Register value = locs()->in(0).reg();
1797 Register result = locs()->out().reg(); 1797 Register result = locs()->out().reg();
1798 ASSERT(value == result); 1798 ASSERT(value == result);
1799 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1799 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1800 instance_call()->token_pos(), 1800 instance_call()->token_pos(),
1801 instance_call()->try_index(), 1801 instance_call()->try_index(),
1802 kDeoptUnaryOp, 1802 kDeoptUnaryOp,
1803 value); 1803 value);
1804 if (test_class_id == kSmi) { 1804 if (test_class_id == kSmi) {
1805 __ testl(value, Immediate(kSmiTagMask)); 1805 __ testl(value, Immediate(kSmiTagMask));
1806 __ j(NOT_ZERO, deopt); 1806 __ j(NOT_ZERO, deopt);
1807 switch (op_kind()) { 1807 switch (op_kind()) {
1808 case Token::kNEGATE: 1808 case Token::kNEGATE:
1809 __ negl(value); 1809 __ negl(value);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1841 1841
1842 // TODO(srdjan): Implement for more checks. 1842 // TODO(srdjan): Implement for more checks.
1843 ASSERT(ic_data.NumberOfChecks() == 1); 1843 ASSERT(ic_data.NumberOfChecks() == 1);
1844 intptr_t test_class_id; 1844 intptr_t test_class_id;
1845 Function& target = Function::Handle(); 1845 Function& target = Function::Handle();
1846 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1846 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1847 1847
1848 Register value = locs()->in(0).reg(); 1848 Register value = locs()->in(0).reg();
1849 Register result = locs()->out().reg(); 1849 Register result = locs()->out().reg();
1850 ASSERT(value == result); 1850 ASSERT(value == result);
1851 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1851 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1852 instance_call()->token_pos(), 1852 instance_call()->token_pos(),
1853 instance_call()->try_index(), 1853 instance_call()->try_index(),
1854 kDeoptUnaryOp, 1854 kDeoptUnaryOp,
1855 value); 1855 value);
1856 if (test_class_id == kDouble) { 1856 if (test_class_id == kDouble) {
1857 Register temp = locs()->temp(0).reg(); 1857 Register temp = locs()->temp(0).reg();
1858 __ testl(value, Immediate(kSmiTagMask)); 1858 __ testl(value, Immediate(kSmiTagMask));
1859 __ j(ZERO, deopt); // Smi. 1859 __ j(ZERO, deopt); // Smi.
1860 __ CompareClassId(value, kDouble, temp); 1860 __ CompareClassId(value, kDouble, temp);
1861 __ j(NOT_EQUAL, deopt); 1861 __ j(NOT_EQUAL, deopt);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 } 1899 }
1900 } 1900 }
1901 1901
1902 1902
1903 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1903 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1904 Register value = (from() == kDouble) ? locs()->in(0).reg() : EBX; 1904 Register value = (from() == kDouble) ? locs()->in(0).reg() : EBX;
1905 Register result = locs()->out().reg(); 1905 Register result = locs()->out().reg();
1906 1906
1907 const DeoptReasonId deopt_reason = (from() == kDouble) ? 1907 const DeoptReasonId deopt_reason = (from() == kDouble) ?
1908 kDeoptDoubleToDouble : kDeoptIntegerToDouble; 1908 kDeoptDoubleToDouble : kDeoptIntegerToDouble;
1909 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1909 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1910 instance_call()->token_pos(), 1910 instance_call()->token_pos(),
1911 instance_call()->try_index(), 1911 instance_call()->try_index(),
1912 deopt_reason, 1912 deopt_reason,
1913 value); 1913 value);
1914 1914
1915 if (from() == kDouble) { 1915 if (from() == kDouble) {
1916 Register temp = locs()->temp(0).reg(); 1916 Register temp = locs()->temp(0).reg();
1917 __ testl(value, Immediate(kSmiTagMask)); 1917 __ testl(value, Immediate(kSmiTagMask));
1918 __ j(ZERO, deopt); // Deoptimize if Smi. 1918 __ j(ZERO, deopt); // Deoptimize if Smi.
1919 __ CompareClassId(value, kDouble, temp); 1919 __ CompareClassId(value, kDouble, temp);
(...skipping 24 matching lines...) Expand all
1944 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1944 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
1945 } 1945 }
1946 1946
1947 1947
1948 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { 1948 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
1949 return MakeCallSummary(); 1949 return MakeCallSummary();
1950 } 1950 }
1951 1951
1952 1952
1953 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1953 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1954 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1954 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1955 instance_call()->token_pos(), 1955 instance_call()->token_pos(),
1956 instance_call()->try_index(), 1956 instance_call()->try_index(),
1957 kDeoptPolymorphicInstanceCallTestFail); 1957 kDeoptPolymorphicInstanceCallTestFail);
1958 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) { 1958 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
1959 __ jmp(deopt); 1959 __ jmp(deopt);
1960 return; 1960 return;
1961 } 1961 }
1962 ASSERT(HasICData()); 1962 ASSERT(HasICData());
1963 ASSERT(ic_data()->num_args_tested() == 1); 1963 ASSERT(ic_data()->num_args_tested() == 1);
1964 Label handle_smi; 1964 Label handle_smi;
1965 Label* is_smi_label = 1965 Label* is_smi_label =
1966 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt; 1966 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt;
1967 1967
1968 // Load receiver into EAX. 1968 // Load receiver into EAX.
1969 __ movl(EAX, 1969 __ movl(EAX,
1970 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize)); 1970 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize));
1971 __ testl(EAX, Immediate(kSmiTagMask)); 1971 __ testl(EAX, Immediate(kSmiTagMask));
1972 __ j(ZERO, is_smi_label); 1972 __ j(ZERO, is_smi_label);
1973 Label done; 1973 Label done;
1974 __ LoadClassId(EDI, EAX); 1974 __ LoadClassId(EDI, EAX);
1975 compiler->EmitTestAndCall(*ic_data(), 1975 compiler->EmitTestAndCall(*ic_data(),
1976 EDI, // Class id register. 1976 EDI, // Class id register.
1977 instance_call()->ArgumentCount(), 1977 instance_call()->ArgumentCount(),
1978 instance_call()->argument_names(), 1978 instance_call()->argument_names(),
1979 deopt, 1979 deopt,
1980 (is_smi_label == &handle_smi) ? &done : NULL, 1980 (is_smi_label == &handle_smi) ? &done : NULL,
1981 instance_call()->cid(), 1981 instance_call()->deopt_id(),
1982 instance_call()->token_pos(), 1982 instance_call()->token_pos(),
1983 instance_call()->try_index()); 1983 instance_call()->try_index());
1984 if (is_smi_label == &handle_smi) { 1984 if (is_smi_label == &handle_smi) {
1985 __ Bind(&handle_smi); 1985 __ Bind(&handle_smi);
1986 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi); 1986 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi);
1987 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 1987 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1988 compiler->GenerateStaticCall(instance_call()->cid(), 1988 compiler->GenerateStaticCall(instance_call()->deopt_id(),
1989 instance_call()->token_pos(), 1989 instance_call()->token_pos(),
1990 instance_call()->try_index(), 1990 instance_call()->try_index(),
1991 target, 1991 target,
1992 instance_call()->ArgumentCount(), 1992 instance_call()->ArgumentCount(),
1993 instance_call()->argument_names()); 1993 instance_call()->argument_names());
1994 } 1994 }
1995 __ Bind(&done); 1995 __ Bind(&done);
1996 } 1996 }
1997 1997
1998 1998
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2052 Register right = locs()->in(1).reg(); 2052 Register right = locs()->in(1).reg();
2053 __ cmpl(left, right); 2053 __ cmpl(left, right);
2054 Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 2054 Condition cond = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
2055 EmitBranchOnCondition(compiler, cond); 2055 EmitBranchOnCondition(compiler, cond);
2056 return; 2056 return;
2057 } 2057 }
2058 // Relational or equality. 2058 // Relational or equality.
2059 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 2059 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
2060 if (ICDataWithBothClassIds(*ic_data(), kSmi)) { 2060 if (ICDataWithBothClassIds(*ic_data(), kSmi)) {
2061 EmitSmiComparisonOp(compiler, *locs(), kind(), this, 2061 EmitSmiComparisonOp(compiler, *locs(), kind(), this,
2062 cid(), token_pos(), try_index()); 2062 deopt_id(), token_pos(), try_index());
2063 return; 2063 return;
2064 } 2064 }
2065 if (ICDataWithBothClassIds(*ic_data(), kDouble)) { 2065 if (ICDataWithBothClassIds(*ic_data(), kDouble)) {
2066 EmitDoubleComparisonOp(compiler, *locs(), kind(), this, 2066 EmitDoubleComparisonOp(compiler, *locs(), kind(), this,
2067 cid(), token_pos(), try_index()); 2067 deopt_id(), token_pos(), try_index());
2068 return; 2068 return;
2069 } 2069 }
2070 // TODO(srdjan): Add Smi/Double, Double/Smi comparisons. 2070 // TODO(srdjan): Add Smi/Double, Double/Smi comparisons.
2071 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { 2071 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) {
2072 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), 2072 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(),
2073 cid(), token_pos(), try_index()); 2073 deopt_id(), token_pos(), try_index());
2074 return; 2074 return;
2075 } 2075 }
2076 // Otherwise polymorphic dispatch? 2076 // Otherwise polymorphic dispatch?
2077 } 2077 }
2078 // Not equal is always split into '==' and negate, 2078 // Not equal is always split into '==' and negate,
2079 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 2079 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
2080 Token::Kind call_kind = (kind() == Token::kNE) ? Token::kEQ : kind(); 2080 Token::Kind call_kind = (kind() == Token::kNE) ? Token::kEQ : kind();
2081 const String& function_name = 2081 const String& function_name =
2082 String::ZoneHandle(Symbols::New(Token::Str(call_kind))); 2082 String::ZoneHandle(Symbols::New(Token::Str(call_kind)));
2083 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 2083 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
2084 cid(), 2084 deopt_id(),
2085 token_pos(), 2085 token_pos(),
2086 try_index()); 2086 try_index());
2087 const intptr_t kNumArguments = 2; 2087 const intptr_t kNumArguments = 2;
2088 const intptr_t kNumArgsChecked = 2; // Type-feedback. 2088 const intptr_t kNumArgsChecked = 2; // Type-feedback.
2089 compiler->GenerateInstanceCall(cid(), 2089 compiler->GenerateInstanceCall(deopt_id(),
2090 token_pos(), 2090 token_pos(),
2091 try_index(), 2091 try_index(),
2092 function_name, 2092 function_name,
2093 kNumArguments, 2093 kNumArguments,
2094 Array::ZoneHandle(), // No optional arguments. 2094 Array::ZoneHandle(), // No optional arguments.
2095 kNumArgsChecked); 2095 kNumArgsChecked);
2096 ASSERT(locs()->out().reg() == EAX); 2096 ASSERT(locs()->out().reg() == EAX);
2097 __ CompareObject(locs()->out().reg(), compiler->bool_true()); 2097 __ CompareObject(locs()->out().reg(), compiler->bool_true());
2098 EmitBranchOnCondition(compiler, branch_condition); 2098 EmitBranchOnCondition(compiler, branch_condition);
2099 } 2099 }
2100 2100
2101 } // namespace dart 2101 } // namespace dart
2102 2102
2103 #undef __ 2103 #undef __
2104 2104
2105 #endif // defined TARGET_ARCH_X64 2105 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698