| 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 |