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

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

Issue 24203004: Dart VM: Simplify code generation for equality operators. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased Created 7 years, 2 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_arm.cc ('k') | runtime/vm/intermediate_language_mips.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 const ICData& original_ic_data) { 303 const ICData& original_ic_data) {
304 if (!compiler->is_optimizing()) { 304 if (!compiler->is_optimizing()) {
305 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 305 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
306 deopt_id, 306 deopt_id,
307 token_pos); 307 token_pos);
308 } 308 }
309 const int kNumberOfArguments = 2; 309 const int kNumberOfArguments = 2;
310 const Array& kNoArgumentNames = Object::null_array(); 310 const Array& kNoArgumentNames = Object::null_array();
311 const int kNumArgumentsChecked = 2; 311 const int kNumArgumentsChecked = 2;
312 312
313 const Immediate& raw_null =
314 Immediate(reinterpret_cast<intptr_t>(Object::null()));
315 Label check_identity;
316 __ cmpl(Address(ESP, 0 * kWordSize), raw_null);
317 __ j(EQUAL, &check_identity);
318 __ cmpl(Address(ESP, 1 * kWordSize), raw_null);
319 __ j(EQUAL, &check_identity);
320
321 ICData& equality_ic_data = ICData::ZoneHandle(); 313 ICData& equality_ic_data = ICData::ZoneHandle();
322 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { 314 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
323 ASSERT(!original_ic_data.IsNull()); 315 ASSERT(!original_ic_data.IsNull());
324 if (original_ic_data.NumberOfChecks() == 0) { 316 if (original_ic_data.NumberOfChecks() == 0) {
325 // IC call for reoptimization populates original ICData. 317 // IC call for reoptimization populates original ICData.
326 equality_ic_data = original_ic_data.raw(); 318 equality_ic_data = original_ic_data.raw();
327 } else { 319 } else {
328 // Megamorphic call. 320 // Megamorphic call.
329 equality_ic_data = original_ic_data.AsUnaryClassChecks(); 321 equality_ic_data = original_ic_data.AsUnaryClassChecks();
330 } 322 }
331 } else { 323 } else {
332 const Array& arguments_descriptor = 324 const Array& arguments_descriptor =
333 Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments, 325 Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments,
334 kNoArgumentNames)); 326 kNoArgumentNames));
335 equality_ic_data = ICData::New(compiler->parsed_function().function(), 327 equality_ic_data = ICData::New(compiler->parsed_function().function(),
336 Symbols::EqualOperator(), 328 Symbols::EqualOperator(),
337 arguments_descriptor, 329 arguments_descriptor,
338 deopt_id, 330 deopt_id,
339 kNumArgumentsChecked); 331 kNumArgumentsChecked);
340 } 332 }
341 compiler->GenerateInstanceCall(deopt_id, 333 compiler->GenerateInstanceCall(deopt_id,
342 token_pos, 334 token_pos,
343 kNumberOfArguments, 335 kNumberOfArguments,
344 kNoArgumentNames, 336 kNoArgumentNames,
345 locs, 337 locs,
346 equality_ic_data); 338 equality_ic_data);
347 Label check_ne;
348 __ jmp(&check_ne);
349
350 __ Bind(&check_identity);
351 Label equality_done;
352 if (compiler->is_optimizing()) {
353 // No need to update IC data.
354 Label is_true;
355 __ popl(EAX);
356 __ popl(EDX);
357 __ cmpl(EAX, EDX);
358 __ j(EQUAL, &is_true);
359 __ LoadObject(EAX, Bool::Get(kind != Token::kEQ));
360 __ jmp(&equality_done);
361 __ Bind(&is_true);
362 __ LoadObject(EAX, Bool::Get(kind == Token::kEQ));
363 if (kind == Token::kNE) {
364 // Skip not-equal result conversion.
365 __ jmp(&equality_done);
366 }
367 } else {
368 // Call stub, load IC data in register. The stub will update ICData if
369 // necessary.
370 Register ic_data_reg = locs->temp(0).reg();
371 ASSERT(ic_data_reg == ECX); // Stub depends on it.
372 __ LoadObject(ic_data_reg, equality_ic_data);
373 compiler->GenerateCall(token_pos,
374 &StubCode::EqualityWithNullArgLabel(),
375 PcDescriptors::kRuntimeCall,
376 locs);
377 __ Drop(2);
378 }
379 __ Bind(&check_ne);
380 if (kind == Token::kNE) { 339 if (kind == Token::kNE) {
381 Label true_label, done; 340 Label true_label, done;
382 // Negate the condition: true label returns false and vice versa. 341 // Negate the condition: true label returns false and vice versa.
383 __ CompareObject(EAX, Bool::True()); 342 __ CompareObject(EAX, Bool::True());
384 __ j(EQUAL, &true_label, Assembler::kNearJump); 343 __ j(EQUAL, &true_label, Assembler::kNearJump);
385 __ LoadObject(EAX, Bool::True()); 344 __ LoadObject(EAX, Bool::True());
386 __ jmp(&done, Assembler::kNearJump); 345 __ jmp(&done, Assembler::kNearJump);
387 __ Bind(&true_label); 346 __ Bind(&true_label);
388 __ LoadObject(EAX, Bool::False()); 347 __ LoadObject(EAX, Bool::False());
389 __ Bind(&done); 348 __ Bind(&done);
390 } 349 }
391 __ Bind(&equality_done);
392 } 350 }
393 351
394 352
395 static void LoadValueCid(FlowGraphCompiler* compiler, 353 static void LoadValueCid(FlowGraphCompiler* compiler,
396 Register value_cid_reg, 354 Register value_cid_reg,
397 Register value_reg, 355 Register value_reg,
398 Label* value_is_smi = NULL) { 356 Label* value_is_smi = NULL) {
399 Label done; 357 Label done;
400 if (value_is_smi == NULL) { 358 if (value_is_smi == NULL) {
401 __ movl(value_cid_reg, Immediate(kSmiCid)); 359 __ movl(value_cid_reg, Immediate(kSmiCid));
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 LocationSummary* locs, 513 LocationSummary* locs,
556 Token::Kind kind, 514 Token::Kind kind,
557 BranchInstr* branch, 515 BranchInstr* branch,
558 const ICData& ic_data, 516 const ICData& ic_data,
559 intptr_t deopt_id, 517 intptr_t deopt_id,
560 intptr_t token_pos) { 518 intptr_t token_pos) {
561 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 519 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
562 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 520 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
563 Register left = locs->in(0).reg(); 521 Register left = locs->in(0).reg();
564 Register right = locs->in(1).reg(); 522 Register right = locs->in(1).reg();
565 const Immediate& raw_null =
566 Immediate(reinterpret_cast<intptr_t>(Object::null()));
567 Label done, identity_compare, non_null_compare;
568 __ cmpl(right, raw_null);
569 __ j(EQUAL, &identity_compare, Assembler::kNearJump);
570 __ cmpl(left, raw_null);
571 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
572 // Comparison with NULL is "===".
573 __ Bind(&identity_compare);
574 __ cmpl(left, right);
575 Condition cond = TokenKindToSmiCondition(kind);
576 if (branch != NULL) {
577 branch->EmitBranchOnCondition(compiler, cond);
578 } else {
579 Register result = locs->out().reg();
580 Label load_true;
581 __ j(cond, &load_true, Assembler::kNearJump);
582 __ LoadObject(result, Bool::False());
583 __ jmp(&done);
584 __ Bind(&load_true);
585 __ LoadObject(result, Bool::True());
586 }
587 __ jmp(&done);
588 __ Bind(&non_null_compare); // Receiver is not null.
589 __ pushl(left); 523 __ pushl(left);
590 __ pushl(right); 524 __ pushl(right);
591 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 525 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
592 deopt_id, token_pos); 526 deopt_id, token_pos);
593 __ Bind(&done);
594 } 527 }
595 528
596 529
597 static Condition FlipCondition(Condition condition) { 530 static Condition FlipCondition(Condition condition) {
598 switch (condition) { 531 switch (condition) {
599 case EQUAL: return EQUAL; 532 case EQUAL: return EQUAL;
600 case NOT_EQUAL: return NOT_EQUAL; 533 case NOT_EQUAL: return NOT_EQUAL;
601 case LESS: return GREATER; 534 case LESS: return GREATER;
602 case LESS_EQUAL: return GREATER_EQUAL; 535 case LESS_EQUAL: return GREATER_EQUAL;
603 case GREATER: return LESS; 536 case GREATER: return LESS;
(...skipping 4629 matching lines...) Expand 10 before | Expand all | Expand 10 after
5233 PcDescriptors::kOther, 5166 PcDescriptors::kOther,
5234 locs()); 5167 locs());
5235 __ Drop(2); // Discard type arguments and receiver. 5168 __ Drop(2); // Discard type arguments and receiver.
5236 } 5169 }
5237 5170
5238 } // namespace dart 5171 } // namespace dart
5239 5172
5240 #undef __ 5173 #undef __
5241 5174
5242 #endif // defined TARGET_ARCH_IA32 5175 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698