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

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

Issue 10860018: Fix null-equality comparison for unoptimized branch code. (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 | « no previous file | 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 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 LocationSummary* locs = 273 LocationSummary* locs =
274 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 274 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
275 locs->set_in(0, Location::RegisterLocation(ECX)); 275 locs->set_in(0, Location::RegisterLocation(ECX));
276 locs->set_in(1, Location::RegisterLocation(EDX)); 276 locs->set_in(1, Location::RegisterLocation(EDX));
277 locs->set_out(Location::RegisterLocation(EAX)); 277 locs->set_out(Location::RegisterLocation(EAX));
278 return locs; 278 return locs;
279 } 279 }
280 280
281 281
282 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 282 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
283 EqualityCompareComp* comp) { 283 intptr_t deopt_id,
284 intptr_t token_pos,
285 intptr_t try_index,
286 Token::Kind kind,
287 const LocationSummary& locs) {
284 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 288 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
285 comp->deopt_id(), 289 deopt_id,
286 comp->token_pos(), 290 token_pos,
287 comp->try_index()); 291 try_index);
288 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 292 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
289 const int kNumberOfArguments = 2; 293 const int kNumberOfArguments = 2;
290 const Array& kNoArgumentNames = Array::Handle(); 294 const Array& kNoArgumentNames = Array::Handle();
291 const int kNumArgumentsChecked = 2; 295 const int kNumArgumentsChecked = 2;
292 296
293 Label done, false_label, true_label; 297 Label done, false_label, true_label;
294 Register left = comp->locs()->in(0).reg(); 298 Register left = locs.in(0).reg();
295 Register right = comp->locs()->in(1).reg(); 299 Register right = locs.in(1).reg();
296 __ popl(right); 300 __ popl(right);
297 __ popl(left); 301 __ popl(left);
298 const Immediate raw_null = 302 const Immediate raw_null =
299 Immediate(reinterpret_cast<intptr_t>(Object::null())); 303 Immediate(reinterpret_cast<intptr_t>(Object::null()));
300 Label check_identity, instance_call; 304 Label check_identity, instance_call;
301 __ cmpl(right, raw_null); 305 __ cmpl(right, raw_null);
302 __ j(EQUAL, &check_identity, Assembler::kNearJump); 306 __ j(EQUAL, &check_identity, Assembler::kNearJump);
303 __ cmpl(left, raw_null); 307 __ cmpl(left, raw_null);
304 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); 308 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump);
305 309
306 __ Bind(&check_identity); 310 __ Bind(&check_identity);
307 __ cmpl(left, right); 311 __ cmpl(left, right);
308 __ j(EQUAL, &true_label); 312 __ j(EQUAL, &true_label);
309 if (comp->kind() == Token::kEQ) { 313 if (kind == Token::kEQ) {
310 __ LoadObject(EAX, compiler->bool_false()); 314 __ LoadObject(EAX, compiler->bool_false());
311 __ jmp(&done); 315 __ jmp(&done);
312 __ Bind(&true_label); 316 __ Bind(&true_label);
313 __ LoadObject(EAX, compiler->bool_true()); 317 __ LoadObject(EAX, compiler->bool_true());
314 __ jmp(&done); 318 __ jmp(&done);
315 } else { 319 } else {
316 ASSERT(comp->kind() == Token::kNE); 320 ASSERT(kind == Token::kNE);
317 __ jmp(&false_label); 321 __ jmp(&false_label);
318 } 322 }
319 323
320 __ Bind(&instance_call); 324 __ Bind(&instance_call);
321 __ pushl(left); 325 __ pushl(left);
322 __ pushl(right); 326 __ pushl(right);
323 compiler->GenerateInstanceCall(comp->deopt_id(), 327 compiler->GenerateInstanceCall(deopt_id,
324 comp->token_pos(), 328 token_pos,
325 comp->try_index(), 329 try_index,
326 operator_name, 330 operator_name,
327 kNumberOfArguments, 331 kNumberOfArguments,
328 kNoArgumentNames, 332 kNoArgumentNames,
329 kNumArgumentsChecked, 333 kNumArgumentsChecked,
330 comp->locs()->stack_bitmap()); 334 locs.stack_bitmap());
331 ASSERT(comp->locs()->out().reg() == EAX); 335 if (kind == Token::kNE) {
332 if (comp->kind() == Token::kNE) {
333 // Negate the condition: true label returns false and vice versa. 336 // Negate the condition: true label returns false and vice versa.
334 __ CompareObject(EAX, compiler->bool_true()); 337 __ CompareObject(EAX, compiler->bool_true());
335 __ j(EQUAL, &true_label, Assembler::kNearJump); 338 __ j(EQUAL, &true_label, Assembler::kNearJump);
336 __ Bind(&false_label); 339 __ Bind(&false_label);
337 __ LoadObject(EAX, compiler->bool_true()); 340 __ LoadObject(EAX, compiler->bool_true());
338 __ jmp(&done, Assembler::kNearJump); 341 __ jmp(&done, Assembler::kNearJump);
339 __ Bind(&true_label); 342 __ Bind(&true_label);
340 __ LoadObject(EAX, compiler->bool_false()); 343 __ LoadObject(EAX, compiler->bool_false());
341 } 344 }
342 __ Bind(&done); 345 __ Bind(&done);
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 return; 654 return;
652 } 655 }
653 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 656 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
654 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(), 657 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
655 deopt_id(), token_pos(), try_index()); 658 deopt_id(), token_pos(), try_index());
656 } else { 659 } else {
657 Register left = locs()->in(0).reg(); 660 Register left = locs()->in(0).reg();
658 Register right = locs()->in(1).reg(); 661 Register right = locs()->in(1).reg();
659 __ pushl(left); 662 __ pushl(left);
660 __ pushl(right); 663 __ pushl(right);
661 EmitEqualityAsInstanceCall(compiler, this); 664 EmitEqualityAsInstanceCall(compiler,
665 deopt_id(),
666 token_pos(),
667 try_index(),
668 kind(),
669 *locs());
670 ASSERT(locs()->out().reg() == EAX);
662 } 671 }
663 } 672 }
664 673
665 674
666 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 675 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
667 const intptr_t kNumInputs = 2; 676 const intptr_t kNumInputs = 2;
668 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) { 677 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) {
669 const intptr_t kNumTemps = 1; 678 const intptr_t kNumTemps = 1;
670 LocationSummary* summary = 679 LocationSummary* summary =
671 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 680 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 1472 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), 2153 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(),
2145 deopt_id(), token_pos(), try_index()); 2154 deopt_id(), token_pos(), try_index());
2146 return; 2155 return;
2147 } 2156 }
2148 // Otherwise polymorphic dispatch? 2157 // Otherwise polymorphic dispatch?
2149 } 2158 }
2150 Register left = locs()->in(0).reg(); 2159 Register left = locs()->in(0).reg();
2151 Register right = locs()->in(1).reg(); 2160 Register right = locs()->in(1).reg();
2152 __ pushl(left); 2161 __ pushl(left);
2153 __ pushl(right); 2162 __ pushl(right);
2154 // Not equal is always split into '==' and negate, 2163 if ((kind() == Token::kNE) || (kind() == Token::kEQ)) {
2164 EmitEqualityAsInstanceCall(compiler,
2165 deopt_id(),
2166 token_pos(),
2167 try_index(),
2168 Token::kEQ, // kNE reverse occurs at branch.
2169 *locs());
2170 } else {
2171 const String& function_name =
2172 String::ZoneHandle(Symbols::New(Token::Str(kind())));
2173 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
2174 deopt_id(),
2175 token_pos(),
2176 try_index());
2177 const intptr_t kNumArguments = 2;
2178 const intptr_t kNumArgsChecked = 2; // Type-feedback.
2179 compiler->GenerateInstanceCall(deopt_id(),
2180 token_pos(),
2181 try_index(),
2182 function_name,
2183 kNumArguments,
2184 Array::ZoneHandle(), // No optional args.
2185 kNumArgsChecked,
2186 locs()->stack_bitmap());
2187 }
2155 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 2188 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
2156 Token::Kind call_kind = (kind() == Token::kNE) ? Token::kEQ : kind();
2157 const String& function_name =
2158 String::ZoneHandle(Symbols::New(Token::Str(call_kind)));
2159 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
2160 deopt_id(),
2161 token_pos(),
2162 try_index());
2163 const intptr_t kNumArguments = 2;
2164 const intptr_t kNumArgsChecked = 2; // Type-feedback.
2165 compiler->GenerateInstanceCall(deopt_id(),
2166 token_pos(),
2167 try_index(),
2168 function_name,
2169 kNumArguments,
2170 Array::ZoneHandle(), // No optional arguments.
2171 kNumArgsChecked,
2172 locs()->stack_bitmap());
2173 __ CompareObject(EAX, compiler->bool_true()); 2189 __ CompareObject(EAX, compiler->bool_true());
2174 EmitBranchOnCondition(compiler, branch_condition); 2190 EmitBranchOnCondition(compiler, branch_condition);
2175 } 2191 }
2176 2192
2177 } // namespace dart 2193 } // namespace dart
2178 2194
2179 #undef __ 2195 #undef __
2180 2196
2181 #endif // defined TARGET_ARCH_X64 2197 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698