| OLD | NEW |
| 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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 const int kNumArgumentsChecked = 2; | 348 const int kNumArgumentsChecked = 2; |
| 349 | 349 |
| 350 const Immediate raw_null = | 350 const Immediate raw_null = |
| 351 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 351 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 352 Label check_identity; | 352 Label check_identity; |
| 353 __ cmpl(Address(ESP, 0 * kWordSize), raw_null); | 353 __ cmpl(Address(ESP, 0 * kWordSize), raw_null); |
| 354 __ j(EQUAL, &check_identity, Assembler::kNearJump); | 354 __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| 355 __ cmpl(Address(ESP, 1 * kWordSize), raw_null); | 355 __ cmpl(Address(ESP, 1 * kWordSize), raw_null); |
| 356 __ j(EQUAL, &check_identity, Assembler::kNearJump); | 356 __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| 357 | 357 |
| 358 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw()); | 358 ICData& equality_ic_data = ICData::ZoneHandle(); |
| 359 if (equality_ic_data.IsNull()) { | 359 if (compiler->is_optimizing()) { |
| 360 ASSERT(!original_ic_data.IsNull()); |
| 361 equality_ic_data = original_ic_data.AsUnaryClassChecks(); |
| 362 } else { |
| 360 equality_ic_data = ICData::New(compiler->parsed_function().function(), | 363 equality_ic_data = ICData::New(compiler->parsed_function().function(), |
| 361 operator_name, | 364 operator_name, |
| 362 deopt_id, | 365 deopt_id, |
| 363 kNumArgumentsChecked); | 366 kNumArgumentsChecked); |
| 364 } | 367 } |
| 365 compiler->GenerateInstanceCall(deopt_id, | 368 compiler->GenerateInstanceCall(deopt_id, |
| 366 token_pos, | 369 token_pos, |
| 367 kNumberOfArguments, | 370 kNumberOfArguments, |
| 368 kNoArgumentNames, | 371 kNoArgumentNames, |
| 369 locs, | 372 locs, |
| 370 equality_ic_data); | 373 equality_ic_data); |
| 371 Label check_ne; | 374 Label check_ne; |
| 372 __ jmp(&check_ne); | 375 __ jmp(&check_ne); |
| 373 | 376 |
| 374 __ Bind(&check_identity); | 377 __ Bind(&check_identity); |
| 375 // Call stub, load IC data in register. The stub will update ICData if | 378 Label equality_done; |
| 376 // necessary. | 379 if (compiler->is_optimizing()) { |
| 377 Register ic_data_reg = locs->temp(0).reg(); | 380 // No need to update IC data. |
| 378 ASSERT(ic_data_reg == ECX); // Stub depends on it. | 381 Label is_true; |
| 379 __ LoadObject(ic_data_reg, equality_ic_data); | 382 __ popl(EAX); |
| 380 compiler->GenerateCall(token_pos, | 383 __ popl(EDX); |
| 381 &StubCode::EqualityWithNullArgLabel(), | 384 __ cmpl(EAX, EDX); |
| 382 PcDescriptors::kOther, | 385 __ j(EQUAL, &is_true); |
| 383 locs); | 386 __ LoadObject(EAX, (kind == Token::kEQ) ? compiler->bool_false() |
| 384 __ Drop(2); | 387 : compiler->bool_true()); |
| 388 __ jmp(&equality_done); |
| 389 __ Bind(&is_true); |
| 390 __ LoadObject(EAX, (kind == Token::kEQ) ? compiler->bool_true() |
| 391 : compiler->bool_false()); |
| 392 if (kind == Token::kNE) { |
| 393 // Skip not-equal result conversion. |
| 394 __ jmp(&equality_done); |
| 395 } |
| 396 } else { |
| 397 // Call stub, load IC data in register. The stub will update ICData if |
| 398 // necessary. |
| 399 Register ic_data_reg = locs->temp(0).reg(); |
| 400 ASSERT(ic_data_reg == ECX); // Stub depends on it. |
| 401 __ LoadObject(ic_data_reg, equality_ic_data); |
| 402 compiler->GenerateCall(token_pos, |
| 403 &StubCode::EqualityWithNullArgLabel(), |
| 404 PcDescriptors::kOther, |
| 405 locs); |
| 406 __ Drop(2); |
| 407 } |
| 385 __ Bind(&check_ne); | 408 __ Bind(&check_ne); |
| 386 if (kind == Token::kNE) { | 409 if (kind == Token::kNE) { |
| 387 Label false_label, true_label, done; | 410 Label false_label, true_label, done; |
| 388 // Negate the condition: true label returns false and vice versa. | 411 // Negate the condition: true label returns false and vice versa. |
| 389 __ CompareObject(EAX, compiler->bool_true()); | 412 __ CompareObject(EAX, compiler->bool_true()); |
| 390 __ j(EQUAL, &true_label, Assembler::kNearJump); | 413 __ j(EQUAL, &true_label, Assembler::kNearJump); |
| 391 __ Bind(&false_label); | 414 __ Bind(&false_label); |
| 392 __ LoadObject(EAX, compiler->bool_true()); | 415 __ LoadObject(EAX, compiler->bool_true()); |
| 393 __ jmp(&done, Assembler::kNearJump); | 416 __ jmp(&done, Assembler::kNearJump); |
| 394 __ Bind(&true_label); | 417 __ Bind(&true_label); |
| 395 __ LoadObject(EAX, compiler->bool_false()); | 418 __ LoadObject(EAX, compiler->bool_false()); |
| 396 __ Bind(&done); | 419 __ Bind(&done); |
| 397 } | 420 } |
| 421 __ Bind(&equality_done); |
| 398 } | 422 } |
| 399 | 423 |
| 400 | 424 |
| 401 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, | 425 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, |
| 402 const ICData& orig_ic_data, | 426 const ICData& orig_ic_data, |
| 403 LocationSummary* locs, | 427 LocationSummary* locs, |
| 404 BranchInstr* branch, | 428 BranchInstr* branch, |
| 405 Token::Kind kind, | 429 Token::Kind kind, |
| 406 intptr_t deopt_id, | 430 intptr_t deopt_id, |
| 407 intptr_t token_pos) { | 431 intptr_t token_pos) { |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 const String& function_name = | 989 const String& function_name = |
| 966 String::ZoneHandle(Symbols::New(Token::Str(kind()))); | 990 String::ZoneHandle(Symbols::New(Token::Str(kind()))); |
| 967 if (!compiler->is_optimizing()) { | 991 if (!compiler->is_optimizing()) { |
| 968 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, | 992 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, |
| 969 deopt_id(), | 993 deopt_id(), |
| 970 token_pos()); | 994 token_pos()); |
| 971 } | 995 } |
| 972 const intptr_t kNumArguments = 2; | 996 const intptr_t kNumArguments = 2; |
| 973 const intptr_t kNumArgsChecked = 2; // Type-feedback. | 997 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 974 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); | 998 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); |
| 975 if (relational_ic_data.IsNull()) { | 999 if (compiler->is_optimizing()) { |
| 1000 ASSERT(!ic_data()->IsNull()); |
| 1001 relational_ic_data = ic_data()->AsUnaryClassChecks(); |
| 1002 } else { |
| 976 relational_ic_data = ICData::New(compiler->parsed_function().function(), | 1003 relational_ic_data = ICData::New(compiler->parsed_function().function(), |
| 977 function_name, | 1004 function_name, |
| 978 deopt_id(), | 1005 deopt_id(), |
| 979 kNumArgsChecked); | 1006 kNumArgsChecked); |
| 980 } | 1007 } |
| 981 compiler->GenerateInstanceCall(deopt_id(), | 1008 compiler->GenerateInstanceCall(deopt_id(), |
| 982 token_pos(), | 1009 token_pos(), |
| 983 kNumArguments, | 1010 kNumArguments, |
| 984 Array::ZoneHandle(), // No optional arguments. | 1011 Array::ZoneHandle(), // No optional arguments. |
| 985 locs(), | 1012 locs(), |
| (...skipping 1684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2670 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. | 2697 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. |
| 2671 __ pxor(value, XMM0); | 2698 __ pxor(value, XMM0); |
| 2672 } | 2699 } |
| 2673 | 2700 |
| 2674 | 2701 |
| 2675 } // namespace dart | 2702 } // namespace dart |
| 2676 | 2703 |
| 2677 #undef __ | 2704 #undef __ |
| 2678 | 2705 |
| 2679 #endif // defined TARGET_ARCH_X64 | 2706 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |