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

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

Issue 594008: Initial implementation of fast path operation for bitwise OR. (Closed)
Patch Set: Fixed bug, added test. Created 10 years, 10 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
« no previous file with comments | « src/fast-codegen.h ('k') | src/ia32/fast-codegen-ia32.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 Visit(expr->value()); 286 Visit(expr->value());
287 } 287 }
288 288
289 289
290 void FastCodeGenSyntaxChecker::VisitThrow(Throw* expr) { 290 void FastCodeGenSyntaxChecker::VisitThrow(Throw* expr) {
291 BAILOUT("Throw"); 291 BAILOUT("Throw");
292 } 292 }
293 293
294 294
295 void FastCodeGenSyntaxChecker::VisitProperty(Property* expr) { 295 void FastCodeGenSyntaxChecker::VisitProperty(Property* expr) {
296 BAILOUT("Property"); 296 // We support named this property references.
297 VariableProxy* proxy = expr->obj()->AsVariableProxy();
298 if (proxy == NULL || !proxy->var()->is_this()) {
299 BAILOUT("Non-this-property reference");
300 }
301 if (!expr->key()->IsPropertyName()) {
302 BAILOUT("Non-named-property reference");
303 }
304
305 // We will only specialize for fields on the object itself.
306 // Expression::IsPropertyName implies that the name is a literal
307 // symbol but we do not assume that.
308 Literal* key = expr->key()->AsLiteral();
309 if (key != NULL && key->handle()->IsString()) {
310 Handle<Object> receiver = info()->receiver();
311 Handle<String> name = Handle<String>::cast(key->handle());
312 LookupResult lookup;
313 receiver->Lookup(*name, &lookup);
314 if (lookup.holder() != *receiver) BAILOUT("Non-own property reference");
315 if (!lookup.type() == FIELD) BAILOUT("Non-field property reference");
316 } else {
317 UNREACHABLE();
318 BAILOUT("Unexpected non-string-literal property key");
319 }
297 } 320 }
298 321
299 322
300 void FastCodeGenSyntaxChecker::VisitCall(Call* expr) { 323 void FastCodeGenSyntaxChecker::VisitCall(Call* expr) {
301 BAILOUT("Call"); 324 BAILOUT("Call");
302 } 325 }
303 326
304 327
305 void FastCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) { 328 void FastCodeGenSyntaxChecker::VisitCallNew(CallNew* expr) {
306 BAILOUT("CallNew"); 329 BAILOUT("CallNew");
307 } 330 }
308 331
309 332
310 void FastCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) { 333 void FastCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) {
311 BAILOUT("CallRuntime"); 334 BAILOUT("CallRuntime");
312 } 335 }
313 336
314 337
315 void FastCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) { 338 void FastCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) {
316 BAILOUT("UnaryOperation"); 339 BAILOUT("UnaryOperation");
317 } 340 }
318 341
319 342
320 void FastCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) { 343 void FastCodeGenSyntaxChecker::VisitCountOperation(CountOperation* expr) {
321 BAILOUT("CountOperation"); 344 BAILOUT("CountOperation");
322 } 345 }
323 346
324 347
325 void FastCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) { 348 void FastCodeGenSyntaxChecker::VisitBinaryOperation(BinaryOperation* expr) {
326 BAILOUT("BinaryOperation"); 349 // We support bitwise OR.
350 switch (expr->op()) {
351 case Token::COMMA:
352 BAILOUT("BinaryOperation COMMA");
353 case Token::OR:
354 BAILOUT("BinaryOperation OR");
355 case Token::AND:
356 BAILOUT("BinaryOperation AND");
357
358 case Token::BIT_OR:
359 // We support expressions nested on the left because they only require
360 // a pair of registers to keep all intermediate values in registers
361 // (i.e., the expression stack has height no more than two).
362 if (!expr->right()->IsLeaf()) BAILOUT("expression nested on right");
363 Visit(expr->left());
364 CHECK_BAILOUT;
365 Visit(expr->right());
366 break;
367
368 case Token::BIT_XOR:
369 BAILOUT("BinaryOperation BIT_XOR");
370 case Token::BIT_AND:
371 BAILOUT("BinaryOperation BIT_AND");
372 case Token::SHL:
373 BAILOUT("BinaryOperation SHL");
374 case Token::SAR:
375 BAILOUT("BinaryOperation SAR");
376 case Token::SHR:
377 BAILOUT("BinaryOperation SHR");
378 case Token::ADD:
379 BAILOUT("BinaryOperation ADD");
380 case Token::SUB:
381 BAILOUT("BinaryOperation SUB");
382 case Token::MUL:
383 BAILOUT("BinaryOperation MUL");
384 case Token::DIV:
385 BAILOUT("BinaryOperation DIV");
386 case Token::MOD:
387 BAILOUT("BinaryOperation MOD");
388 default:
389 UNREACHABLE();
390 }
327 } 391 }
328 392
329 393
330 void FastCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) { 394 void FastCodeGenSyntaxChecker::VisitCompareOperation(CompareOperation* expr) {
331 BAILOUT("CompareOperation"); 395 BAILOUT("CompareOperation");
332 } 396 }
333 397
334 398
335 void FastCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) { 399 void FastCodeGenSyntaxChecker::VisitThisFunction(ThisFunction* expr) {
336 BAILOUT("ThisFunction"); 400 BAILOUT("ThisFunction");
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 } 546 }
483 547
484 548
485 void FastCodeGenerator::VisitSlot(Slot* expr) { 549 void FastCodeGenerator::VisitSlot(Slot* expr) {
486 UNREACHABLE(); 550 UNREACHABLE();
487 } 551 }
488 552
489 553
490 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { 554 void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
491 ASSERT(expr->var()->is_global() && !expr->var()->is_this()); 555 ASSERT(expr->var()->is_global() && !expr->var()->is_this());
492 Comment cmnt(masm(), ";; Global");
493 if (FLAG_print_ir) {
494 SmartPointer<char> name = expr->name()->ToCString();
495 PrintF("%d: t%d = Global(%s)\n", expr->num(), expr->num(), *name);
496 }
497
498 // Check if we can compile a global variable load directly from the cell. 556 // Check if we can compile a global variable load directly from the cell.
499 ASSERT(info()->has_global_object()); 557 ASSERT(info()->has_global_object());
500 LookupResult lookup; 558 LookupResult lookup;
501 info()->global_object()->Lookup(*expr->name(), &lookup); 559 info()->global_object()->Lookup(*expr->name(), &lookup);
502 // We only support DontDelete properties for now. 560 // We only support DontDelete properties for now.
503 ASSERT(lookup.IsValid()); 561 ASSERT(lookup.IsValid());
504 ASSERT(lookup.IsDontDelete()); 562 ASSERT(lookup.IsDontDelete());
505 Handle<Object> cell(info()->global_object()->GetPropertyCell(&lookup)); 563 Handle<Object> cell(info()->global_object()->GetPropertyCell(&lookup));
506 EmitGlobalVariableLoad(cell); 564
565 // Global variable lookups do not have side effects, so we do not need to
566 // emit code if we are in an effect context.
567 if (!destination().is(no_reg)) {
568 Comment cmnt(masm(), ";; Global");
569 if (FLAG_print_ir) {
570 SmartPointer<char> name = expr->name()->ToCString();
571 PrintF("%d: t%d = Global(%s)\n", expr->num(), expr->num(), *name);
572 }
573 EmitGlobalVariableLoad(cell);
574 }
507 } 575 }
508 576
509 577
510 void FastCodeGenerator::VisitLiteral(Literal* expr) { 578 void FastCodeGenerator::VisitLiteral(Literal* expr) {
511 UNREACHABLE(); 579 UNREACHABLE();
512 } 580 }
513 581
514 582
515 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 583 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
516 UNREACHABLE(); 584 UNREACHABLE();
517 } 585 }
518 586
519 587
520 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 588 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
521 UNREACHABLE(); 589 UNREACHABLE();
522 } 590 }
523 591
524 592
525 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 593 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
526 UNREACHABLE(); 594 UNREACHABLE();
527 } 595 }
528 596
529 597
530 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { 598 void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
531 UNREACHABLE(); 599 UNREACHABLE();
532 } 600 }
533 601
534 602
535 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 603 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
536 // Known to be a simple this property assignment. 604 // Known to be a simple this property assignment. Effectively a unary
537 Visit(expr->value()); 605 // operation.
606 { Register my_destination = destination();
607 set_destination(accumulator0());
608 Visit(expr->value());
609 set_destination(my_destination);
610 }
538 611
539 Property* prop = expr->target()->AsProperty(); 612 Property* prop = expr->target()->AsProperty();
540 ASSERT_NOT_NULL(prop); 613 ASSERT_NOT_NULL(prop);
541 ASSERT_NOT_NULL(prop->obj()->AsVariableProxy()); 614 ASSERT_NOT_NULL(prop->obj()->AsVariableProxy());
542 ASSERT(prop->obj()->AsVariableProxy()->var()->is_this()); 615 ASSERT(prop->obj()->AsVariableProxy()->var()->is_this());
543 ASSERT(prop->key()->IsPropertyName()); 616 ASSERT(prop->key()->IsPropertyName());
544 Handle<String> name = 617 Handle<String> name =
545 Handle<String>::cast(prop->key()->AsLiteral()->handle()); 618 Handle<String>::cast(prop->key()->AsLiteral()->handle());
546 619
547 Comment cmnt(masm(), ";; Store(this)"); 620 Comment cmnt(masm(), ";; Store to this");
548 if (FLAG_print_ir) { 621 if (FLAG_print_ir) {
549 SmartPointer<char> name_string = name->ToCString(); 622 SmartPointer<char> name_string = name->ToCString();
550 PrintF("%d: t%d = Store(this, \"%s\", t%d)\n", 623 PrintF("%d: ", expr->num());
551 expr->num(), expr->num(), *name_string, expr->value()->num()); 624 if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
625 PrintF("Store(this, \"%s\", t%d)\n", *name_string, expr->value()->num());
552 } 626 }
553 627
554 EmitThisPropertyStore(name); 628 EmitThisPropertyStore(name);
555 } 629 }
556 630
557 631
558 void FastCodeGenerator::VisitThrow(Throw* expr) { 632 void FastCodeGenerator::VisitThrow(Throw* expr) {
559 UNREACHABLE(); 633 UNREACHABLE();
560 } 634 }
561 635
562 636
563 void FastCodeGenerator::VisitProperty(Property* expr) { 637 void FastCodeGenerator::VisitProperty(Property* expr) {
564 UNREACHABLE(); 638 ASSERT_NOT_NULL(expr->obj()->AsVariableProxy());
639 ASSERT(expr->obj()->AsVariableProxy()->var()->is_this());
640 ASSERT(expr->key()->IsPropertyName());
641 if (!destination().is(no_reg)) {
642 Handle<String> name =
643 Handle<String>::cast(expr->key()->AsLiteral()->handle());
644
645 Comment cmnt(masm(), ";; Load from this");
646 if (FLAG_print_ir) {
647 SmartPointer<char> name_string = name->ToCString();
648 PrintF("%d: t%d = Load(this, \"%s\")\n",
649 expr->num(), expr->num(), *name_string);
650 }
651 EmitThisPropertyLoad(name);
652 }
565 } 653 }
566 654
567 655
568 void FastCodeGenerator::VisitCall(Call* expr) { 656 void FastCodeGenerator::VisitCall(Call* expr) {
569 UNREACHABLE(); 657 UNREACHABLE();
570 } 658 }
571 659
572 660
573 void FastCodeGenerator::VisitCallNew(CallNew* expr) { 661 void FastCodeGenerator::VisitCallNew(CallNew* expr) {
574 UNREACHABLE(); 662 UNREACHABLE();
575 } 663 }
576 664
577 665
578 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 666 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
579 UNREACHABLE(); 667 UNREACHABLE();
580 } 668 }
581 669
582 670
583 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 671 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
584 UNREACHABLE(); 672 UNREACHABLE();
585 } 673 }
586 674
587 675
588 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { 676 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) {
589 UNREACHABLE(); 677 UNREACHABLE();
590 } 678 }
591 679
592 680
593 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 681 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
594 UNREACHABLE(); 682 // We support limited binary operations: bitwise OR only allowed to be
683 // nested on the left.
684 ASSERT(expr->op() == Token::BIT_OR);
685 ASSERT(expr->right()->IsLeaf());
686
687 { Register my_destination = destination();
688 set_destination(accumulator1());
689 Visit(expr->left());
690 set_destination(accumulator0());
691 Visit(expr->right());
692 set_destination(my_destination);
693 }
694
695 Comment cmnt(masm(), ";; BIT_OR");
696 if (FLAG_print_ir) {
697 PrintF("%d: ", expr->num());
698 if (!destination().is(no_reg)) PrintF("t%d = ", expr->num());
699 PrintF("BIT_OR(t%d, t%d)\n", expr->left()->num(), expr->right()->num());
700 }
701 EmitBitOr();
595 } 702 }
596 703
597 704
598 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { 705 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
599 UNREACHABLE(); 706 UNREACHABLE();
600 } 707 }
601 708
602 709
603 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { 710 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) {
604 UNREACHABLE(); 711 UNREACHABLE();
605 } 712 }
606 713
607 #undef __ 714 #undef __
608 715
609 716
610 } } // namespace v8::internal 717 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/fast-codegen.h ('k') | src/ia32/fast-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698