OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { | 398 void FullCodeGenerator::StackValueContext::Plug(Variable* var) const { |
399 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 399 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
400 codegen()->GetVar(result_register(), var); | 400 codegen()->GetVar(result_register(), var); |
401 __ push(result_register()); | 401 __ push(result_register()); |
402 } | 402 } |
403 | 403 |
404 | 404 |
405 void FullCodeGenerator::TestContext::Plug(Variable* var) const { | 405 void FullCodeGenerator::TestContext::Plug(Variable* var) const { |
406 // For simplicity we always test the accumulator register. | 406 // For simplicity we always test the accumulator register. |
407 codegen()->GetVar(result_register(), var); | 407 codegen()->GetVar(result_register(), var); |
408 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); | 408 codegen()->PrepareForBailoutBeforeSplit(false, NULL, NULL); |
409 codegen()->DoTest(this); | 409 codegen()->DoTest(this); |
410 } | 410 } |
411 | 411 |
412 | 412 |
413 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 413 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
414 } | 414 } |
415 | 415 |
416 | 416 |
417 void FullCodeGenerator::AccumulatorValueContext::Plug( | 417 void FullCodeGenerator::AccumulatorValueContext::Plug( |
418 Heap::RootListIndex index) const { | 418 Heap::RootListIndex index) const { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 __ sw(reg, MemOperand(sp, 0)); | 515 __ sw(reg, MemOperand(sp, 0)); |
516 } | 516 } |
517 | 517 |
518 | 518 |
519 void FullCodeGenerator::TestContext::DropAndPlug(int count, | 519 void FullCodeGenerator::TestContext::DropAndPlug(int count, |
520 Register reg) const { | 520 Register reg) const { |
521 ASSERT(count > 0); | 521 ASSERT(count > 0); |
522 // For simplicity we always test the accumulator register. | 522 // For simplicity we always test the accumulator register. |
523 __ Drop(count); | 523 __ Drop(count); |
524 __ Move(result_register(), reg); | 524 __ Move(result_register(), reg); |
525 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); | 525 codegen()->PrepareForBailoutBeforeSplit(false, NULL, NULL); |
526 codegen()->DoTest(this); | 526 codegen()->DoTest(this); |
527 } | 527 } |
528 | 528 |
529 | 529 |
530 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, | 530 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, |
531 Label* materialize_false) const { | 531 Label* materialize_false) const { |
532 ASSERT(materialize_true == materialize_false); | 532 ASSERT(materialize_true == materialize_false); |
533 __ bind(materialize_true); | 533 __ bind(materialize_true); |
534 } | 534 } |
535 | 535 |
(...skipping 1870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2406 | 2406 |
2407 VisitForAccumulatorValue(args->at(0)); | 2407 VisitForAccumulatorValue(args->at(0)); |
2408 | 2408 |
2409 Label materialize_true, materialize_false; | 2409 Label materialize_true, materialize_false; |
2410 Label* if_true = NULL; | 2410 Label* if_true = NULL; |
2411 Label* if_false = NULL; | 2411 Label* if_false = NULL; |
2412 Label* fall_through = NULL; | 2412 Label* fall_through = NULL; |
2413 context()->PrepareTest(&materialize_true, &materialize_false, | 2413 context()->PrepareTest(&materialize_true, &materialize_false, |
2414 &if_true, &if_false, &fall_through); | 2414 &if_true, &if_false, &fall_through); |
2415 | 2415 |
2416 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2416 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2417 __ And(t0, v0, Operand(kSmiTagMask)); | 2417 __ And(t0, v0, Operand(kSmiTagMask)); |
2418 Split(eq, t0, Operand(zero_reg), if_true, if_false, fall_through); | 2418 Split(eq, t0, Operand(zero_reg), if_true, if_false, fall_through); |
2419 | 2419 |
2420 context()->Plug(if_true, if_false); | 2420 context()->Plug(if_true, if_false); |
2421 } | 2421 } |
2422 | 2422 |
2423 | 2423 |
2424 void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) { | 2424 void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) { |
2425 ASSERT(args->length() == 1); | 2425 ASSERT(args->length() == 1); |
2426 | 2426 |
2427 VisitForAccumulatorValue(args->at(0)); | 2427 VisitForAccumulatorValue(args->at(0)); |
2428 | 2428 |
2429 Label materialize_true, materialize_false; | 2429 Label materialize_true, materialize_false; |
2430 Label* if_true = NULL; | 2430 Label* if_true = NULL; |
2431 Label* if_false = NULL; | 2431 Label* if_false = NULL; |
2432 Label* fall_through = NULL; | 2432 Label* fall_through = NULL; |
2433 context()->PrepareTest(&materialize_true, &materialize_false, | 2433 context()->PrepareTest(&materialize_true, &materialize_false, |
2434 &if_true, &if_false, &fall_through); | 2434 &if_true, &if_false, &fall_through); |
2435 | 2435 |
2436 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2436 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2437 __ And(at, v0, Operand(kSmiTagMask | 0x80000000)); | 2437 __ And(at, v0, Operand(kSmiTagMask | 0x80000000)); |
2438 Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through); | 2438 Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through); |
2439 | 2439 |
2440 context()->Plug(if_true, if_false); | 2440 context()->Plug(if_true, if_false); |
2441 } | 2441 } |
2442 | 2442 |
2443 | 2443 |
2444 void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) { | 2444 void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) { |
2445 ASSERT(args->length() == 1); | 2445 ASSERT(args->length() == 1); |
2446 | 2446 |
2447 VisitForAccumulatorValue(args->at(0)); | 2447 VisitForAccumulatorValue(args->at(0)); |
2448 | 2448 |
2449 Label materialize_true, materialize_false; | 2449 Label materialize_true, materialize_false; |
2450 Label* if_true = NULL; | 2450 Label* if_true = NULL; |
2451 Label* if_false = NULL; | 2451 Label* if_false = NULL; |
2452 Label* fall_through = NULL; | 2452 Label* fall_through = NULL; |
2453 context()->PrepareTest(&materialize_true, &materialize_false, | 2453 context()->PrepareTest(&materialize_true, &materialize_false, |
2454 &if_true, &if_false, &fall_through); | 2454 &if_true, &if_false, &fall_through); |
2455 | 2455 |
2456 __ JumpIfSmi(v0, if_false); | 2456 __ JumpIfSmi(v0, if_false); |
2457 __ LoadRoot(at, Heap::kNullValueRootIndex); | 2457 __ LoadRoot(at, Heap::kNullValueRootIndex); |
2458 __ Branch(if_true, eq, v0, Operand(at)); | 2458 __ Branch(if_true, eq, v0, Operand(at)); |
2459 __ lw(a2, FieldMemOperand(v0, HeapObject::kMapOffset)); | 2459 __ lw(a2, FieldMemOperand(v0, HeapObject::kMapOffset)); |
2460 // Undetectable objects behave like undefined when tested with typeof. | 2460 // Undetectable objects behave like undefined when tested with typeof. |
2461 __ lbu(a1, FieldMemOperand(a2, Map::kBitFieldOffset)); | 2461 __ lbu(a1, FieldMemOperand(a2, Map::kBitFieldOffset)); |
2462 __ And(at, a1, Operand(1 << Map::kIsUndetectable)); | 2462 __ And(at, a1, Operand(1 << Map::kIsUndetectable)); |
2463 __ Branch(if_false, ne, at, Operand(zero_reg)); | 2463 __ Branch(if_false, ne, at, Operand(zero_reg)); |
2464 __ lbu(a1, FieldMemOperand(a2, Map::kInstanceTypeOffset)); | 2464 __ lbu(a1, FieldMemOperand(a2, Map::kInstanceTypeOffset)); |
2465 __ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2465 __ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
2466 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2466 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2467 Split(le, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE), | 2467 Split(le, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE), |
2468 if_true, if_false, fall_through); | 2468 if_true, if_false, fall_through); |
2469 | 2469 |
2470 context()->Plug(if_true, if_false); | 2470 context()->Plug(if_true, if_false); |
2471 } | 2471 } |
2472 | 2472 |
2473 | 2473 |
2474 void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) { | 2474 void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) { |
2475 ASSERT(args->length() == 1); | 2475 ASSERT(args->length() == 1); |
2476 | 2476 |
2477 VisitForAccumulatorValue(args->at(0)); | 2477 VisitForAccumulatorValue(args->at(0)); |
2478 | 2478 |
2479 Label materialize_true, materialize_false; | 2479 Label materialize_true, materialize_false; |
2480 Label* if_true = NULL; | 2480 Label* if_true = NULL; |
2481 Label* if_false = NULL; | 2481 Label* if_false = NULL; |
2482 Label* fall_through = NULL; | 2482 Label* fall_through = NULL; |
2483 context()->PrepareTest(&materialize_true, &materialize_false, | 2483 context()->PrepareTest(&materialize_true, &materialize_false, |
2484 &if_true, &if_false, &fall_through); | 2484 &if_true, &if_false, &fall_through); |
2485 | 2485 |
2486 __ JumpIfSmi(v0, if_false); | 2486 __ JumpIfSmi(v0, if_false); |
2487 __ GetObjectType(v0, a1, a1); | 2487 __ GetObjectType(v0, a1, a1); |
2488 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2488 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2489 Split(ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE), | 2489 Split(ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE), |
2490 if_true, if_false, fall_through); | 2490 if_true, if_false, fall_through); |
2491 | 2491 |
2492 context()->Plug(if_true, if_false); | 2492 context()->Plug(if_true, if_false); |
2493 } | 2493 } |
2494 | 2494 |
2495 | 2495 |
2496 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { | 2496 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { |
2497 ASSERT(args->length() == 1); | 2497 ASSERT(args->length() == 1); |
2498 | 2498 |
2499 VisitForAccumulatorValue(args->at(0)); | 2499 VisitForAccumulatorValue(args->at(0)); |
2500 | 2500 |
2501 Label materialize_true, materialize_false; | 2501 Label materialize_true, materialize_false; |
2502 Label* if_true = NULL; | 2502 Label* if_true = NULL; |
2503 Label* if_false = NULL; | 2503 Label* if_false = NULL; |
2504 Label* fall_through = NULL; | 2504 Label* fall_through = NULL; |
2505 context()->PrepareTest(&materialize_true, &materialize_false, | 2505 context()->PrepareTest(&materialize_true, &materialize_false, |
2506 &if_true, &if_false, &fall_through); | 2506 &if_true, &if_false, &fall_through); |
2507 | 2507 |
2508 __ JumpIfSmi(v0, if_false); | 2508 __ JumpIfSmi(v0, if_false); |
2509 __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); | 2509 __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); |
2510 __ lbu(a1, FieldMemOperand(a1, Map::kBitFieldOffset)); | 2510 __ lbu(a1, FieldMemOperand(a1, Map::kBitFieldOffset)); |
2511 __ And(at, a1, Operand(1 << Map::kIsUndetectable)); | 2511 __ And(at, a1, Operand(1 << Map::kIsUndetectable)); |
2512 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2512 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2513 Split(ne, at, Operand(zero_reg), if_true, if_false, fall_through); | 2513 Split(ne, at, Operand(zero_reg), if_true, if_false, fall_through); |
2514 | 2514 |
2515 context()->Plug(if_true, if_false); | 2515 context()->Plug(if_true, if_false); |
2516 } | 2516 } |
2517 | 2517 |
2518 | 2518 |
2519 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( | 2519 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( |
2520 ZoneList<Expression*>* args) { | 2520 ZoneList<Expression*>* args) { |
2521 | 2521 |
2522 ASSERT(args->length() == 1); | 2522 ASSERT(args->length() == 1); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2587 __ lw(a3, ContextOperand(a3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); | 2587 __ lw(a3, ContextOperand(a3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); |
2588 __ Branch(if_false, ne, a2, Operand(a3)); | 2588 __ Branch(if_false, ne, a2, Operand(a3)); |
2589 | 2589 |
2590 // Set the bit in the map to indicate that it has been checked safe for | 2590 // Set the bit in the map to indicate that it has been checked safe for |
2591 // default valueOf and set true result. | 2591 // default valueOf and set true result. |
2592 __ lbu(a2, FieldMemOperand(a1, Map::kBitField2Offset)); | 2592 __ lbu(a2, FieldMemOperand(a1, Map::kBitField2Offset)); |
2593 __ Or(a2, a2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); | 2593 __ Or(a2, a2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); |
2594 __ sb(a2, FieldMemOperand(a1, Map::kBitField2Offset)); | 2594 __ sb(a2, FieldMemOperand(a1, Map::kBitField2Offset)); |
2595 __ jmp(if_true); | 2595 __ jmp(if_true); |
2596 | 2596 |
2597 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2597 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2598 context()->Plug(if_true, if_false); | 2598 context()->Plug(if_true, if_false); |
2599 } | 2599 } |
2600 | 2600 |
2601 | 2601 |
2602 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { | 2602 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { |
2603 ASSERT(args->length() == 1); | 2603 ASSERT(args->length() == 1); |
2604 | 2604 |
2605 VisitForAccumulatorValue(args->at(0)); | 2605 VisitForAccumulatorValue(args->at(0)); |
2606 | 2606 |
2607 Label materialize_true, materialize_false; | 2607 Label materialize_true, materialize_false; |
2608 Label* if_true = NULL; | 2608 Label* if_true = NULL; |
2609 Label* if_false = NULL; | 2609 Label* if_false = NULL; |
2610 Label* fall_through = NULL; | 2610 Label* fall_through = NULL; |
2611 context()->PrepareTest(&materialize_true, &materialize_false, | 2611 context()->PrepareTest(&materialize_true, &materialize_false, |
2612 &if_true, &if_false, &fall_through); | 2612 &if_true, &if_false, &fall_through); |
2613 | 2613 |
2614 __ JumpIfSmi(v0, if_false); | 2614 __ JumpIfSmi(v0, if_false); |
2615 __ GetObjectType(v0, a1, a2); | 2615 __ GetObjectType(v0, a1, a2); |
2616 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2616 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2617 __ Branch(if_true, eq, a2, Operand(JS_FUNCTION_TYPE)); | 2617 __ Branch(if_true, eq, a2, Operand(JS_FUNCTION_TYPE)); |
2618 __ Branch(if_false); | 2618 __ Branch(if_false); |
2619 | 2619 |
2620 context()->Plug(if_true, if_false); | 2620 context()->Plug(if_true, if_false); |
2621 } | 2621 } |
2622 | 2622 |
2623 | 2623 |
2624 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { | 2624 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { |
2625 ASSERT(args->length() == 1); | 2625 ASSERT(args->length() == 1); |
2626 | 2626 |
2627 VisitForAccumulatorValue(args->at(0)); | 2627 VisitForAccumulatorValue(args->at(0)); |
2628 | 2628 |
2629 Label materialize_true, materialize_false; | 2629 Label materialize_true, materialize_false; |
2630 Label* if_true = NULL; | 2630 Label* if_true = NULL; |
2631 Label* if_false = NULL; | 2631 Label* if_false = NULL; |
2632 Label* fall_through = NULL; | 2632 Label* fall_through = NULL; |
2633 context()->PrepareTest(&materialize_true, &materialize_false, | 2633 context()->PrepareTest(&materialize_true, &materialize_false, |
2634 &if_true, &if_false, &fall_through); | 2634 &if_true, &if_false, &fall_through); |
2635 | 2635 |
2636 __ JumpIfSmi(v0, if_false); | 2636 __ JumpIfSmi(v0, if_false); |
2637 __ GetObjectType(v0, a1, a1); | 2637 __ GetObjectType(v0, a1, a1); |
2638 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2638 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2639 Split(eq, a1, Operand(JS_ARRAY_TYPE), | 2639 Split(eq, a1, Operand(JS_ARRAY_TYPE), |
2640 if_true, if_false, fall_through); | 2640 if_true, if_false, fall_through); |
2641 | 2641 |
2642 context()->Plug(if_true, if_false); | 2642 context()->Plug(if_true, if_false); |
2643 } | 2643 } |
2644 | 2644 |
2645 | 2645 |
2646 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { | 2646 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { |
2647 ASSERT(args->length() == 1); | 2647 ASSERT(args->length() == 1); |
2648 | 2648 |
2649 VisitForAccumulatorValue(args->at(0)); | 2649 VisitForAccumulatorValue(args->at(0)); |
2650 | 2650 |
2651 Label materialize_true, materialize_false; | 2651 Label materialize_true, materialize_false; |
2652 Label* if_true = NULL; | 2652 Label* if_true = NULL; |
2653 Label* if_false = NULL; | 2653 Label* if_false = NULL; |
2654 Label* fall_through = NULL; | 2654 Label* fall_through = NULL; |
2655 context()->PrepareTest(&materialize_true, &materialize_false, | 2655 context()->PrepareTest(&materialize_true, &materialize_false, |
2656 &if_true, &if_false, &fall_through); | 2656 &if_true, &if_false, &fall_through); |
2657 | 2657 |
2658 __ JumpIfSmi(v0, if_false); | 2658 __ JumpIfSmi(v0, if_false); |
2659 __ GetObjectType(v0, a1, a1); | 2659 __ GetObjectType(v0, a1, a1); |
2660 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2660 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2661 Split(eq, a1, Operand(JS_REGEXP_TYPE), if_true, if_false, fall_through); | 2661 Split(eq, a1, Operand(JS_REGEXP_TYPE), if_true, if_false, fall_through); |
2662 | 2662 |
2663 context()->Plug(if_true, if_false); | 2663 context()->Plug(if_true, if_false); |
2664 } | 2664 } |
2665 | 2665 |
2666 | 2666 |
2667 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { | 2667 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { |
2668 ASSERT(args->length() == 0); | 2668 ASSERT(args->length() == 0); |
2669 | 2669 |
2670 Label materialize_true, materialize_false; | 2670 Label materialize_true, materialize_false; |
2671 Label* if_true = NULL; | 2671 Label* if_true = NULL; |
2672 Label* if_false = NULL; | 2672 Label* if_false = NULL; |
2673 Label* fall_through = NULL; | 2673 Label* fall_through = NULL; |
2674 context()->PrepareTest(&materialize_true, &materialize_false, | 2674 context()->PrepareTest(&materialize_true, &materialize_false, |
2675 &if_true, &if_false, &fall_through); | 2675 &if_true, &if_false, &fall_through); |
2676 | 2676 |
2677 // Get the frame pointer for the calling frame. | 2677 // Get the frame pointer for the calling frame. |
2678 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 2678 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
2679 | 2679 |
2680 // Skip the arguments adaptor frame if it exists. | 2680 // Skip the arguments adaptor frame if it exists. |
2681 Label check_frame_marker; | 2681 Label check_frame_marker; |
2682 __ lw(a1, MemOperand(a2, StandardFrameConstants::kContextOffset)); | 2682 __ lw(a1, MemOperand(a2, StandardFrameConstants::kContextOffset)); |
2683 __ Branch(&check_frame_marker, ne, | 2683 __ Branch(&check_frame_marker, ne, |
2684 a1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 2684 a1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
2685 __ lw(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset)); | 2685 __ lw(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset)); |
2686 | 2686 |
2687 // Check the marker in the calling frame. | 2687 // Check the marker in the calling frame. |
2688 __ bind(&check_frame_marker); | 2688 __ bind(&check_frame_marker); |
2689 __ lw(a1, MemOperand(a2, StandardFrameConstants::kMarkerOffset)); | 2689 __ lw(a1, MemOperand(a2, StandardFrameConstants::kMarkerOffset)); |
2690 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2690 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2691 Split(eq, a1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)), | 2691 Split(eq, a1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)), |
2692 if_true, if_false, fall_through); | 2692 if_true, if_false, fall_through); |
2693 | 2693 |
2694 context()->Plug(if_true, if_false); | 2694 context()->Plug(if_true, if_false); |
2695 } | 2695 } |
2696 | 2696 |
2697 | 2697 |
2698 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { | 2698 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { |
2699 ASSERT(args->length() == 2); | 2699 ASSERT(args->length() == 2); |
2700 | 2700 |
2701 // Load the two objects into registers and perform the comparison. | 2701 // Load the two objects into registers and perform the comparison. |
2702 VisitForStackValue(args->at(0)); | 2702 VisitForStackValue(args->at(0)); |
2703 VisitForAccumulatorValue(args->at(1)); | 2703 VisitForAccumulatorValue(args->at(1)); |
2704 | 2704 |
2705 Label materialize_true, materialize_false; | 2705 Label materialize_true, materialize_false; |
2706 Label* if_true = NULL; | 2706 Label* if_true = NULL; |
2707 Label* if_false = NULL; | 2707 Label* if_false = NULL; |
2708 Label* fall_through = NULL; | 2708 Label* fall_through = NULL; |
2709 context()->PrepareTest(&materialize_true, &materialize_false, | 2709 context()->PrepareTest(&materialize_true, &materialize_false, |
2710 &if_true, &if_false, &fall_through); | 2710 &if_true, &if_false, &fall_through); |
2711 | 2711 |
2712 __ pop(a1); | 2712 __ pop(a1); |
2713 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2713 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
2714 Split(eq, v0, Operand(a1), if_true, if_false, fall_through); | 2714 Split(eq, v0, Operand(a1), if_true, if_false, fall_through); |
2715 | 2715 |
2716 context()->Plug(if_true, if_false); | 2716 context()->Plug(if_true, if_false); |
2717 } | 2717 } |
2718 | 2718 |
2719 | 2719 |
2720 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { | 2720 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { |
2721 ASSERT(args->length() == 1); | 2721 ASSERT(args->length() == 1); |
2722 | 2722 |
2723 // ArgumentsAccessStub expects the key in a1 and the formal | 2723 // ArgumentsAccessStub expects the key in a1 and the formal |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3389 Label materialize_true, materialize_false; | 3389 Label materialize_true, materialize_false; |
3390 Label* if_true = NULL; | 3390 Label* if_true = NULL; |
3391 Label* if_false = NULL; | 3391 Label* if_false = NULL; |
3392 Label* fall_through = NULL; | 3392 Label* fall_through = NULL; |
3393 context()->PrepareTest(&materialize_true, &materialize_false, | 3393 context()->PrepareTest(&materialize_true, &materialize_false, |
3394 &if_true, &if_false, &fall_through); | 3394 &if_true, &if_false, &fall_through); |
3395 | 3395 |
3396 __ lw(a0, FieldMemOperand(v0, String::kHashFieldOffset)); | 3396 __ lw(a0, FieldMemOperand(v0, String::kHashFieldOffset)); |
3397 __ And(a0, a0, Operand(String::kContainsCachedArrayIndexMask)); | 3397 __ And(a0, a0, Operand(String::kContainsCachedArrayIndexMask)); |
3398 | 3398 |
3399 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 3399 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
3400 Split(eq, a0, Operand(zero_reg), if_true, if_false, fall_through); | 3400 Split(eq, a0, Operand(zero_reg), if_true, if_false, fall_through); |
3401 | 3401 |
3402 context()->Plug(if_true, if_false); | 3402 context()->Plug(if_true, if_false); |
3403 } | 3403 } |
3404 | 3404 |
3405 | 3405 |
3406 void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { | 3406 void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { |
3407 ASSERT(args->length() == 1); | 3407 ASSERT(args->length() == 1); |
3408 VisitForAccumulatorValue(args->at(0)); | 3408 VisitForAccumulatorValue(args->at(0)); |
3409 | 3409 |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4041 Label materialize_true, materialize_false; | 4041 Label materialize_true, materialize_false; |
4042 Label* if_true = NULL; | 4042 Label* if_true = NULL; |
4043 Label* if_false = NULL; | 4043 Label* if_false = NULL; |
4044 Label* fall_through = NULL; | 4044 Label* fall_through = NULL; |
4045 context()->PrepareTest(&materialize_true, &materialize_false, | 4045 context()->PrepareTest(&materialize_true, &materialize_false, |
4046 &if_true, &if_false, &fall_through); | 4046 &if_true, &if_false, &fall_through); |
4047 | 4047 |
4048 { AccumulatorValueContext context(this); | 4048 { AccumulatorValueContext context(this); |
4049 VisitForTypeofValue(expr); | 4049 VisitForTypeofValue(expr); |
4050 } | 4050 } |
4051 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4051 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
4052 | 4052 |
4053 if (check->Equals(isolate()->heap()->number_symbol())) { | 4053 if (check->Equals(isolate()->heap()->number_symbol())) { |
4054 __ JumpIfSmi(v0, if_true); | 4054 __ JumpIfSmi(v0, if_true); |
4055 __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset)); | 4055 __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset)); |
4056 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 4056 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
4057 Split(eq, v0, Operand(at), if_true, if_false, fall_through); | 4057 Split(eq, v0, Operand(at), if_true, if_false, fall_through); |
4058 } else if (check->Equals(isolate()->heap()->string_symbol())) { | 4058 } else if (check->Equals(isolate()->heap()->string_symbol())) { |
4059 __ JumpIfSmi(v0, if_false); | 4059 __ JumpIfSmi(v0, if_false); |
4060 // Check for undetectable objects => false. | 4060 // Check for undetectable objects => false. |
4061 __ GetObjectType(v0, v0, a1); | 4061 __ GetObjectType(v0, v0, a1); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4127 Label* fall_through = NULL; | 4127 Label* fall_through = NULL; |
4128 context()->PrepareTest(&materialize_true, &materialize_false, | 4128 context()->PrepareTest(&materialize_true, &materialize_false, |
4129 &if_true, &if_false, &fall_through); | 4129 &if_true, &if_false, &fall_through); |
4130 | 4130 |
4131 Token::Value op = expr->op(); | 4131 Token::Value op = expr->op(); |
4132 VisitForStackValue(expr->left()); | 4132 VisitForStackValue(expr->left()); |
4133 switch (op) { | 4133 switch (op) { |
4134 case Token::IN: | 4134 case Token::IN: |
4135 VisitForStackValue(expr->right()); | 4135 VisitForStackValue(expr->right()); |
4136 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); | 4136 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
4137 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); | 4137 PrepareForBailoutBeforeSplit(false, NULL, NULL); |
4138 __ LoadRoot(t0, Heap::kTrueValueRootIndex); | 4138 __ LoadRoot(t0, Heap::kTrueValueRootIndex); |
4139 Split(eq, v0, Operand(t0), if_true, if_false, fall_through); | 4139 Split(eq, v0, Operand(t0), if_true, if_false, fall_through); |
4140 break; | 4140 break; |
4141 | 4141 |
4142 case Token::INSTANCEOF: { | 4142 case Token::INSTANCEOF: { |
4143 VisitForStackValue(expr->right()); | 4143 VisitForStackValue(expr->right()); |
4144 InstanceofStub stub(InstanceofStub::kNoFlags); | 4144 InstanceofStub stub(InstanceofStub::kNoFlags); |
4145 __ CallStub(&stub); | 4145 __ CallStub(&stub); |
4146 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4146 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
4147 // The stub returns 0 for true. | 4147 // The stub returns 0 for true. |
4148 Split(eq, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4148 Split(eq, v0, Operand(zero_reg), if_true, if_false, fall_through); |
4149 break; | 4149 break; |
4150 } | 4150 } |
4151 | 4151 |
4152 default: { | 4152 default: { |
4153 VisitForAccumulatorValue(expr->right()); | 4153 VisitForAccumulatorValue(expr->right()); |
4154 Condition cc = eq; | 4154 Condition cc = eq; |
4155 switch (op) { | 4155 switch (op) { |
4156 case Token::EQ_STRICT: | 4156 case Token::EQ_STRICT: |
(...skipping 27 matching lines...) Expand all Loading... |
4184 __ Or(a2, a0, Operand(a1)); | 4184 __ Or(a2, a0, Operand(a1)); |
4185 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 4185 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
4186 Split(cc, a1, Operand(a0), if_true, if_false, NULL); | 4186 Split(cc, a1, Operand(a0), if_true, if_false, NULL); |
4187 __ bind(&slow_case); | 4187 __ bind(&slow_case); |
4188 } | 4188 } |
4189 // Record position and call the compare IC. | 4189 // Record position and call the compare IC. |
4190 SetSourcePosition(expr->position()); | 4190 SetSourcePosition(expr->position()); |
4191 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4191 Handle<Code> ic = CompareIC::GetUninitialized(op); |
4192 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); | 4192 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
4193 patch_site.EmitPatchInfo(); | 4193 patch_site.EmitPatchInfo(); |
4194 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4194 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
4195 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4195 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); |
4196 } | 4196 } |
4197 } | 4197 } |
4198 | 4198 |
4199 // Convert the result of the comparison into one expected for this | 4199 // Convert the result of the comparison into one expected for this |
4200 // expression's context. | 4200 // expression's context. |
4201 context()->Plug(if_true, if_false); | 4201 context()->Plug(if_true, if_false); |
4202 } | 4202 } |
4203 | 4203 |
4204 | 4204 |
4205 void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, | 4205 void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, |
4206 Expression* sub_expr, | 4206 Expression* sub_expr, |
4207 NilValue nil) { | 4207 NilValue nil) { |
4208 Label materialize_true, materialize_false; | 4208 Label materialize_true, materialize_false; |
4209 Label* if_true = NULL; | 4209 Label* if_true = NULL; |
4210 Label* if_false = NULL; | 4210 Label* if_false = NULL; |
4211 Label* fall_through = NULL; | 4211 Label* fall_through = NULL; |
4212 context()->PrepareTest(&materialize_true, &materialize_false, | 4212 context()->PrepareTest(&materialize_true, &materialize_false, |
4213 &if_true, &if_false, &fall_through); | 4213 &if_true, &if_false, &fall_through); |
4214 | 4214 |
4215 VisitForAccumulatorValue(sub_expr); | 4215 VisitForAccumulatorValue(sub_expr); |
4216 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4216 PrepareForBailoutBeforeSplit(true, if_true, if_false); |
4217 Heap::RootListIndex nil_value = nil == kNullValue ? | 4217 Heap::RootListIndex nil_value = nil == kNullValue ? |
4218 Heap::kNullValueRootIndex : | 4218 Heap::kNullValueRootIndex : |
4219 Heap::kUndefinedValueRootIndex; | 4219 Heap::kUndefinedValueRootIndex; |
4220 __ mov(a0, result_register()); | 4220 __ mov(a0, result_register()); |
4221 __ LoadRoot(a1, nil_value); | 4221 __ LoadRoot(a1, nil_value); |
4222 if (expr->op() == Token::EQ_STRICT) { | 4222 if (expr->op() == Token::EQ_STRICT) { |
4223 Split(eq, a0, Operand(a1), if_true, if_false, fall_through); | 4223 Split(eq, a0, Operand(a1), if_true, if_false, fall_through); |
4224 } else { | 4224 } else { |
4225 Heap::RootListIndex other_nil_value = nil == kNullValue ? | 4225 Heap::RootListIndex other_nil_value = nil == kNullValue ? |
4226 Heap::kUndefinedValueRootIndex : | 4226 Heap::kUndefinedValueRootIndex : |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4343 *context_length = 0; | 4343 *context_length = 0; |
4344 return previous_; | 4344 return previous_; |
4345 } | 4345 } |
4346 | 4346 |
4347 | 4347 |
4348 #undef __ | 4348 #undef __ |
4349 | 4349 |
4350 } } // namespace v8::internal | 4350 } } // namespace v8::internal |
4351 | 4351 |
4352 #endif // V8_TARGET_ARCH_MIPS | 4352 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |