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

Side by Side Diff: src/x64/fast-codegen-x64.cc

Issue 542105: Fix a bug in the short-circuit logical operations in the toplevel... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Fix a bug in the short-circuit logical operations in the toplevel... Created 10 years, 11 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 | « src/ia32/fast-codegen-ia32.cc ('k') | src/x64/virtual-frame-x64.h » ('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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 switch (location_) { 214 switch (location_) {
215 case kAccumulator: 215 case kAccumulator:
216 if (!reg.is(result_register())) __ movq(result_register(), reg); 216 if (!reg.is(result_register())) __ movq(result_register(), reg);
217 break; 217 break;
218 case kStack: 218 case kStack:
219 __ push(reg); 219 __ push(reg);
220 break; 220 break;
221 } 221 }
222 break; 222 break;
223 223
224 case Expression::kValueTest:
225 case Expression::kTestValue:
226 // Push an extra copy of the value in case it's needed.
227 __ push(reg);
228 // Fall through.
229
230 case Expression::kTest: 224 case Expression::kTest:
231 // For simplicity we always test the accumulator register. 225 // For simplicity we always test the accumulator register.
232 if (!reg.is(result_register())) __ movq(result_register(), reg); 226 if (!reg.is(result_register())) __ movq(result_register(), reg);
233 DoTest(context); 227 DoTest(context);
234 break; 228 break;
229
230 case Expression::kValueTest:
231 case Expression::kTestValue:
232 if (!reg.is(result_register())) __ movq(result_register(), reg);
233 switch (location_) {
234 case kAccumulator:
235 break;
236 case kStack:
237 __ push(result_register());
238 break;
239 }
240 DoTest(context);
241 break;
235 } 242 }
236 } 243 }
237 244
238 245
239 void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) { 246 void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) {
240 switch (context) { 247 switch (context) {
241 case Expression::kUninitialized: 248 case Expression::kUninitialized:
242 UNREACHABLE(); 249 UNREACHABLE();
243 case Expression::kEffect: 250 case Expression::kEffect:
244 // Nothing to do. 251 // Nothing to do.
(...skipping 13 matching lines...) Expand all
258 } 265 }
259 266
260 case Expression::kTest: 267 case Expression::kTest:
261 Move(result_register(), slot); 268 Move(result_register(), slot);
262 DoTest(context); 269 DoTest(context);
263 break; 270 break;
264 271
265 case Expression::kValueTest: 272 case Expression::kValueTest:
266 case Expression::kTestValue: 273 case Expression::kTestValue:
267 Move(result_register(), slot); 274 Move(result_register(), slot);
268 __ push(result_register()); 275 switch (location_) {
276 case kAccumulator:
277 break;
278 case kStack:
279 __ push(result_register());
280 break;
281 }
269 DoTest(context); 282 DoTest(context);
270 break; 283 break;
271 } 284 }
272 } 285 }
273 286
274 287
275 void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) { 288 void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) {
276 switch (context) { 289 switch (context) {
277 case Expression::kUninitialized: 290 case Expression::kUninitialized:
278 UNREACHABLE(); 291 UNREACHABLE();
(...skipping 12 matching lines...) Expand all
291 break; 304 break;
292 305
293 case Expression::kTest: 306 case Expression::kTest:
294 __ Move(result_register(), lit->handle()); 307 __ Move(result_register(), lit->handle());
295 DoTest(context); 308 DoTest(context);
296 break; 309 break;
297 310
298 case Expression::kValueTest: 311 case Expression::kValueTest:
299 case Expression::kTestValue: 312 case Expression::kTestValue:
300 __ Move(result_register(), lit->handle()); 313 __ Move(result_register(), lit->handle());
301 __ push(result_register()); 314 switch (location_) {
315 case kAccumulator:
316 break;
317 case kStack:
318 __ push(result_register());
319 break;
320 }
302 DoTest(context); 321 DoTest(context);
303 break; 322 break;
304 } 323 }
305 } 324 }
306 325
307 326
308 void FastCodeGenerator::ApplyTOS(Expression::Context context) { 327 void FastCodeGenerator::ApplyTOS(Expression::Context context) {
309 switch (context) { 328 switch (context) {
310 case Expression::kUninitialized: 329 case Expression::kUninitialized:
311 UNREACHABLE(); 330 UNREACHABLE();
(...skipping 12 matching lines...) Expand all
324 } 343 }
325 break; 344 break;
326 345
327 case Expression::kTest: 346 case Expression::kTest:
328 __ pop(result_register()); 347 __ pop(result_register());
329 DoTest(context); 348 DoTest(context);
330 break; 349 break;
331 350
332 case Expression::kValueTest: 351 case Expression::kValueTest:
333 case Expression::kTestValue: 352 case Expression::kTestValue:
334 __ movq(result_register(), Operand(rsp, 0)); 353 switch (location_) {
354 case kAccumulator:
355 __ pop(result_register());
356 break;
357 case kStack:
358 __ movq(result_register(), Operand(rsp, 0));
359 break;
360 }
335 DoTest(context); 361 DoTest(context);
336 break; 362 break;
337 } 363 }
338 } 364 }
339 365
340 366
341 void FastCodeGenerator::DropAndApply(int count, 367 void FastCodeGenerator::DropAndApply(int count,
342 Expression::Context context, 368 Expression::Context context,
343 Register reg) { 369 Register reg) {
344 ASSERT(count > 0); 370 ASSERT(count > 0);
(...skipping 20 matching lines...) Expand all
365 break; 391 break;
366 392
367 case Expression::kTest: 393 case Expression::kTest:
368 __ Drop(count); 394 __ Drop(count);
369 if (!reg.is(result_register())) __ movq(result_register(), reg); 395 if (!reg.is(result_register())) __ movq(result_register(), reg);
370 DoTest(context); 396 DoTest(context);
371 break; 397 break;
372 398
373 case Expression::kValueTest: 399 case Expression::kValueTest:
374 case Expression::kTestValue: 400 case Expression::kTestValue:
375 if (count > 1) __ Drop(count - 1); 401 switch (location_) {
376 if (!reg.is(result_register())) __ movq(result_register(), reg); 402 case kAccumulator:
377 __ movq(Operand(rsp, 0), result_register()); 403 __ Drop(count);
404 if (!reg.is(result_register())) __ movq(result_register(), reg);
405 break;
406 case kStack:
407 if (count > 1) __ Drop(count - 1);
408 __ movq(result_register(), reg);
409 __ movq(Operand(rsp, 0), result_register());
410 break;
411 }
378 DoTest(context); 412 DoTest(context);
379 break; 413 break;
380 } 414 }
381 } 415 }
382 416
383 417
384 void FastCodeGenerator::Apply(Expression::Context context, 418 void FastCodeGenerator::Apply(Expression::Context context,
385 Label* materialize_true, 419 Label* materialize_true,
386 Label* materialize_false) { 420 Label* materialize_false) {
387 switch (context) { 421 switch (context) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 __ Push(Factory::false_value()); 473 __ Push(Factory::false_value());
440 break; 474 break;
441 } 475 }
442 __ jmp(false_label_); 476 __ jmp(false_label_);
443 break; 477 break;
444 } 478 }
445 } 479 }
446 480
447 481
448 void FastCodeGenerator::DoTest(Expression::Context context) { 482 void FastCodeGenerator::DoTest(Expression::Context context) {
449 // The value to test is in the accumulator, and duplicated on the stack if 483 // The value to test is in the accumulator. If the value might be needed
450 // necessary (for value/test and test/value contexts). 484 // on the stack (value/test and test/value contexts with a stack location
485 // desired), then the value is already duplicated on the stack.
451 ASSERT_NE(NULL, true_label_); 486 ASSERT_NE(NULL, true_label_);
452 ASSERT_NE(NULL, false_label_); 487 ASSERT_NE(NULL, false_label_);
453 488
454 // If there is a value on the stack, use a discard label for the 489 // In value/test and test/value expression contexts with stack as the
455 // value-is-unneeded branch in the inlined part of the test. 490 // desired location, there is already an extra value on the stack. Use a
491 // label to discard it if unneeded.
456 Label discard; 492 Label discard;
457 Label* if_true = 493 Label* if_true = true_label_;
458 (context == Expression::kTestValue) ? &discard : true_label_; 494 Label* if_false = false_label_;
459 Label* if_false = 495 switch (context) {
460 (context == Expression::kValueTest) ? &discard : false_label_; 496 case Expression::kUninitialized:
497 case Expression::kEffect:
498 case Expression::kValue:
499 UNREACHABLE();
500 case Expression::kTest:
501 break;
502 case Expression::kValueTest:
503 switch (location_) {
504 case kAccumulator:
505 break;
506 case kStack:
507 if_false = &discard;
508 break;
509 }
510 break;
511 case Expression::kTestValue:
512 switch (location_) {
513 case kAccumulator:
514 break;
515 case kStack:
516 if_true = &discard;
517 break;
518 }
519 break;
520 }
461 521
462 // Emit the inlined tests assumed by the stub. 522 // Emit the inlined tests assumed by the stub.
463 __ CompareRoot(result_register(), Heap::kUndefinedValueRootIndex); 523 __ CompareRoot(result_register(), Heap::kUndefinedValueRootIndex);
464 __ j(equal, if_false); 524 __ j(equal, if_false);
465 __ CompareRoot(result_register(), Heap::kTrueValueRootIndex); 525 __ CompareRoot(result_register(), Heap::kTrueValueRootIndex);
466 __ j(equal, if_true); 526 __ j(equal, if_true);
467 __ CompareRoot(result_register(), Heap::kFalseValueRootIndex); 527 __ CompareRoot(result_register(), Heap::kFalseValueRootIndex);
468 __ j(equal, if_false); 528 __ j(equal, if_false);
469 ASSERT_EQ(0, kSmiTag); 529 ASSERT_EQ(0, kSmiTag);
470 __ SmiCompare(result_register(), Smi::FromInt(0)); 530 __ SmiCompare(result_register(), Smi::FromInt(0));
471 __ j(equal, if_false); 531 __ j(equal, if_false);
472 Condition is_smi = masm_->CheckSmi(result_register()); 532 Condition is_smi = masm_->CheckSmi(result_register());
473 __ j(is_smi, if_true); 533 __ j(is_smi, if_true);
474 534
535 // Save a copy of the value if it may be needed and isn't already saved.
536 switch (context) {
537 case Expression::kUninitialized:
538 case Expression::kEffect:
539 case Expression::kValue:
540 UNREACHABLE();
541 case Expression::kTest:
542 break;
543 case Expression::kValueTest:
544 switch (location_) {
545 case kAccumulator:
546 __ push(result_register());
547 break;
548 case kStack:
549 break;
550 }
551 break;
552 case Expression::kTestValue:
553 switch (location_) {
554 case kAccumulator:
555 __ push(result_register());
556 break;
557 case kStack:
558 break;
559 }
560 break;
561 }
562
475 // Call the ToBoolean stub for all other cases. 563 // Call the ToBoolean stub for all other cases.
476 ToBooleanStub stub; 564 ToBooleanStub stub;
477 __ push(result_register()); 565 __ push(result_register());
478 __ CallStub(&stub); 566 __ CallStub(&stub);
479 __ testq(rax, rax); 567 __ testq(rax, rax);
480 568
481 // The stub returns nonzero for true. Complete based on the context. 569 // The stub returns nonzero for true. Complete based on the context.
482 switch (context) { 570 switch (context) {
483 case Expression::kUninitialized: 571 case Expression::kUninitialized:
484 case Expression::kEffect: 572 case Expression::kEffect:
(...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1722 __ movq(Operand(rsp, 0), rdx); 1810 __ movq(Operand(rsp, 0), rdx);
1723 // And return. 1811 // And return.
1724 __ ret(0); 1812 __ ret(0);
1725 } 1813 }
1726 1814
1727 1815
1728 #undef __ 1816 #undef __
1729 1817
1730 1818
1731 } } // namespace v8::internal 1819 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/fast-codegen-ia32.cc ('k') | src/x64/virtual-frame-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698