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

Side by Side Diff: runtime/vm/intermediate_language_x64.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 | « runtime/vm/intermediate_language_ia32.cc ('k') | tests/co19/co19-dart2js.status » ('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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 LocationSummary* locs = 282 LocationSummary* locs =
283 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 283 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
284 locs->set_in(0, Location::RegisterLocation(RCX)); 284 locs->set_in(0, Location::RegisterLocation(RCX));
285 locs->set_in(1, Location::RegisterLocation(RDX)); 285 locs->set_in(1, Location::RegisterLocation(RDX));
286 locs->set_out(Location::RegisterLocation(RAX)); 286 locs->set_out(Location::RegisterLocation(RAX));
287 return locs; 287 return locs;
288 } 288 }
289 289
290 290
291 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 291 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
292 EqualityCompareComp* comp) { 292 intptr_t deopt_id,
293 intptr_t token_pos,
294 intptr_t try_index,
295 Token::Kind kind,
296 const LocationSummary& locs) {
293 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 297 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
294 comp->deopt_id(), 298 deopt_id,
295 comp->token_pos(), 299 token_pos,
296 comp->try_index()); 300 try_index);
297 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 301 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
298 const int kNumberOfArguments = 2; 302 const int kNumberOfArguments = 2;
299 const Array& kNoArgumentNames = Array::Handle(); 303 const Array& kNoArgumentNames = Array::Handle();
300 const int kNumArgumentsChecked = 2; 304 const int kNumArgumentsChecked = 2;
301 305
302 Label done, false_label, true_label; 306 Label done, false_label, true_label;
303 Register left = comp->locs()->in(0).reg(); 307 Register left = locs.in(0).reg();
304 Register right = comp->locs()->in(1).reg(); 308 Register right = locs.in(1).reg();
305 __ popq(right); 309 __ popq(right);
306 __ popq(left); 310 __ popq(left);
307 const Immediate raw_null = 311 const Immediate raw_null =
308 Immediate(reinterpret_cast<intptr_t>(Object::null())); 312 Immediate(reinterpret_cast<intptr_t>(Object::null()));
309 Label check_identity, instance_call; 313 Label check_identity, instance_call;
310 __ cmpq(right, raw_null); 314 __ cmpq(right, raw_null);
311 __ j(EQUAL, &check_identity, Assembler::kNearJump); 315 __ j(EQUAL, &check_identity, Assembler::kNearJump);
312 __ cmpq(left, raw_null); 316 __ cmpq(left, raw_null);
313 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); 317 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump);
314 318
315 __ Bind(&check_identity); 319 __ Bind(&check_identity);
316 __ cmpq(left, right); 320 __ cmpq(left, right);
317 __ j(EQUAL, &true_label); 321 __ j(EQUAL, &true_label);
318 if (comp->kind() == Token::kEQ) { 322 if (kind == Token::kEQ) {
319 __ LoadObject(RAX, compiler->bool_false()); 323 __ LoadObject(RAX, compiler->bool_false());
320 __ jmp(&done); 324 __ jmp(&done);
321 __ Bind(&true_label); 325 __ Bind(&true_label);
322 __ LoadObject(RAX, compiler->bool_true()); 326 __ LoadObject(RAX, compiler->bool_true());
323 __ jmp(&done); 327 __ jmp(&done);
324 } else { 328 } else {
325 ASSERT(comp->kind() == Token::kNE); 329 ASSERT(kind == Token::kNE);
326 __ jmp(&false_label); 330 __ jmp(&false_label);
327 } 331 }
328 332
329 __ Bind(&instance_call); 333 __ Bind(&instance_call);
330 __ pushq(left); 334 __ pushq(left);
331 __ pushq(right); 335 __ pushq(right);
332 compiler->GenerateInstanceCall(comp->deopt_id(), 336 compiler->GenerateInstanceCall(deopt_id,
333 comp->token_pos(), 337 token_pos,
334 comp->try_index(), 338 try_index,
335 operator_name, 339 operator_name,
336 kNumberOfArguments, 340 kNumberOfArguments,
337 kNoArgumentNames, 341 kNoArgumentNames,
338 kNumArgumentsChecked, 342 kNumArgumentsChecked,
339 comp->locs()->stack_bitmap()); 343 locs.stack_bitmap());
340 ASSERT(comp->locs()->out().reg() == RAX); 344 if (kind == Token::kNE) {
341 if (comp->kind() == Token::kNE) {
342 // Negate the condition: true label returns false and vice versa. 345 // Negate the condition: true label returns false and vice versa.
343 __ CompareObject(RAX, compiler->bool_true()); 346 __ CompareObject(RAX, compiler->bool_true());
344 __ j(EQUAL, &true_label, Assembler::kNearJump); 347 __ j(EQUAL, &true_label, Assembler::kNearJump);
345 __ Bind(&false_label); 348 __ Bind(&false_label);
346 __ LoadObject(RAX, compiler->bool_true()); 349 __ LoadObject(RAX, compiler->bool_true());
347 __ jmp(&done, Assembler::kNearJump); 350 __ jmp(&done, Assembler::kNearJump);
348 __ Bind(&true_label); 351 __ Bind(&true_label);
349 __ LoadObject(RAX, compiler->bool_false()); 352 __ LoadObject(RAX, compiler->bool_false());
350 } 353 }
351 __ Bind(&done); 354 __ Bind(&done);
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 return; 664 return;
662 } 665 }
663 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 666 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
664 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(), 667 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(),
665 deopt_id(), token_pos(), try_index()); 668 deopt_id(), token_pos(), try_index());
666 } else { 669 } else {
667 Register left = locs()->in(0).reg(); 670 Register left = locs()->in(0).reg();
668 Register right = locs()->in(1).reg(); 671 Register right = locs()->in(1).reg();
669 __ pushq(left); 672 __ pushq(left);
670 __ pushq(right); 673 __ pushq(right);
671 EmitEqualityAsInstanceCall(compiler, this); 674 EmitEqualityAsInstanceCall(compiler,
675 deopt_id(),
676 token_pos(),
677 try_index(),
678 kind(),
679 *locs());
680 ASSERT(locs()->out().reg() == RAX);
672 } 681 }
673 } 682 }
674 683
675 684
676 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 685 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
677 const intptr_t kNumInputs = 2; 686 const intptr_t kNumInputs = 2;
678 if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) { 687 if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) {
679 const intptr_t kNumTemps = 1; 688 const intptr_t kNumTemps = 1;
680 LocationSummary* summary = 689 LocationSummary* summary =
681 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 690 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 1475 matching lines...) Expand 10 before | Expand all | Expand 10 after
2157 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), 2166 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(),
2158 deopt_id(), token_pos(), try_index()); 2167 deopt_id(), token_pos(), try_index());
2159 return; 2168 return;
2160 } 2169 }
2161 // Otherwise polymorphic dispatch? 2170 // Otherwise polymorphic dispatch?
2162 } 2171 }
2163 Register left = locs()->in(0).reg(); 2172 Register left = locs()->in(0).reg();
2164 Register right = locs()->in(1).reg(); 2173 Register right = locs()->in(1).reg();
2165 __ pushq(left); 2174 __ pushq(left);
2166 __ pushq(right); 2175 __ pushq(right);
2167 // Not equal is always split into '==' and negate, 2176 if ((kind() == Token::kNE) || (kind() == Token::kEQ)) {
2177 EmitEqualityAsInstanceCall(compiler,
2178 deopt_id(),
2179 token_pos(),
2180 try_index(),
2181 Token::kEQ, // kNE reverse occurs at branch.
2182 *locs());
2183 } else {
2184 const String& function_name =
2185 String::ZoneHandle(Symbols::New(Token::Str(kind())));
2186 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
2187 deopt_id(),
2188 token_pos(),
2189 try_index());
2190 const intptr_t kNumArguments = 2;
2191 const intptr_t kNumArgsChecked = 2; // Type-feedback.
2192 compiler->GenerateInstanceCall(deopt_id(),
2193 token_pos(),
2194 try_index(),
2195 function_name,
2196 kNumArguments,
2197 Array::ZoneHandle(), // No optional args.
2198 kNumArgsChecked,
2199 locs()->stack_bitmap());
2200 }
2168 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 2201 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
2169 Token::Kind call_kind = (kind() == Token::kNE) ? Token::kEQ : kind();
2170 const String& function_name =
2171 String::ZoneHandle(Symbols::New(Token::Str(call_kind)));
2172 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
2173 deopt_id(),
2174 token_pos(),
2175 try_index());
2176 const intptr_t kNumArguments = 2;
2177 const intptr_t kNumArgsChecked = 2; // Type-feedback.
2178 compiler->GenerateInstanceCall(deopt_id(),
2179 token_pos(),
2180 try_index(),
2181 function_name,
2182 kNumArguments,
2183 Array::ZoneHandle(), // No optional arguments.
2184 kNumArgsChecked,
2185 locs()->stack_bitmap());
2186 __ CompareObject(RAX, compiler->bool_true()); 2202 __ CompareObject(RAX, compiler->bool_true());
2187 EmitBranchOnCondition(compiler, branch_condition); 2203 EmitBranchOnCondition(compiler, branch_condition);
2188 } 2204 }
2189 2205
2190 } // namespace dart 2206 } // namespace dart
2191 2207
2192 #undef __ 2208 #undef __
2193 2209
2194 #endif // defined TARGET_ARCH_X64 2210 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | tests/co19/co19-dart2js.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698