| 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(false, NULL, NULL); | 408 codegen()->PrepareForBailoutBeforeSplit(condition(), 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 { |
| 419 __ LoadRoot(result_register(), index); | 419 __ LoadRoot(result_register(), index); |
| 420 } | 420 } |
| 421 | 421 |
| 422 | 422 |
| 423 void FullCodeGenerator::StackValueContext::Plug( | 423 void FullCodeGenerator::StackValueContext::Plug( |
| 424 Heap::RootListIndex index) const { | 424 Heap::RootListIndex index) const { |
| 425 __ LoadRoot(result_register(), index); | 425 __ LoadRoot(result_register(), index); |
| 426 __ push(result_register()); | 426 __ push(result_register()); |
| 427 } | 427 } |
| 428 | 428 |
| 429 | 429 |
| 430 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { | 430 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { |
| 431 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, | 431 codegen()->PrepareForBailoutBeforeSplit(condition(), |
| 432 true, | 432 true, |
| 433 true_label_, | 433 true_label_, |
| 434 false_label_); | 434 false_label_); |
| 435 if (index == Heap::kUndefinedValueRootIndex || | 435 if (index == Heap::kUndefinedValueRootIndex || |
| 436 index == Heap::kNullValueRootIndex || | 436 index == Heap::kNullValueRootIndex || |
| 437 index == Heap::kFalseValueRootIndex) { | 437 index == Heap::kFalseValueRootIndex) { |
| 438 if (false_label_ != fall_through_) __ Branch(false_label_); | 438 if (false_label_ != fall_through_) __ Branch(false_label_); |
| 439 } else if (index == Heap::kTrueValueRootIndex) { | 439 } else if (index == Heap::kTrueValueRootIndex) { |
| 440 if (true_label_ != fall_through_) __ Branch(true_label_); | 440 if (true_label_ != fall_through_) __ Branch(true_label_); |
| 441 } else { | 441 } else { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 456 | 456 |
| 457 | 457 |
| 458 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { | 458 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { |
| 459 // Immediates cannot be pushed directly. | 459 // Immediates cannot be pushed directly. |
| 460 __ li(result_register(), Operand(lit)); | 460 __ li(result_register(), Operand(lit)); |
| 461 __ push(result_register()); | 461 __ push(result_register()); |
| 462 } | 462 } |
| 463 | 463 |
| 464 | 464 |
| 465 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { | 465 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { |
| 466 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, | 466 codegen()->PrepareForBailoutBeforeSplit(condition(), |
| 467 true, | 467 true, |
| 468 true_label_, | 468 true_label_, |
| 469 false_label_); | 469 false_label_); |
| 470 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals. | 470 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals. |
| 471 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { | 471 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { |
| 472 if (false_label_ != fall_through_) __ Branch(false_label_); | 472 if (false_label_ != fall_through_) __ Branch(false_label_); |
| 473 } else if (lit->IsTrue() || lit->IsJSObject()) { | 473 } else if (lit->IsTrue() || lit->IsJSObject()) { |
| 474 if (true_label_ != fall_through_) __ Branch(true_label_); | 474 if (true_label_ != fall_through_) __ Branch(true_label_); |
| 475 } else if (lit->IsString()) { | 475 } else if (lit->IsString()) { |
| 476 if (String::cast(*lit)->length() == 0) { | 476 if (String::cast(*lit)->length() == 0) { |
| (...skipping 38 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(false, NULL, NULL); | 525 codegen()->PrepareForBailoutBeforeSplit(condition(), 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 | 582 |
| 583 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 583 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 584 Heap::RootListIndex value_root_index = | 584 Heap::RootListIndex value_root_index = |
| 585 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 585 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 586 __ LoadRoot(at, value_root_index); | 586 __ LoadRoot(at, value_root_index); |
| 587 __ push(at); | 587 __ push(at); |
| 588 } | 588 } |
| 589 | 589 |
| 590 | 590 |
| 591 void FullCodeGenerator::TestContext::Plug(bool flag) const { | 591 void FullCodeGenerator::TestContext::Plug(bool flag) const { |
| 592 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, | 592 codegen()->PrepareForBailoutBeforeSplit(condition(), |
| 593 true, | 593 true, |
| 594 true_label_, | 594 true_label_, |
| 595 false_label_); | 595 false_label_); |
| 596 if (flag) { | 596 if (flag) { |
| 597 if (true_label_ != fall_through_) __ Branch(true_label_); | 597 if (true_label_ != fall_through_) __ Branch(true_label_); |
| 598 } else { | 598 } else { |
| 599 if (false_label_ != fall_through_) __ Branch(false_label_); | 599 if (false_label_ != fall_through_) __ Branch(false_label_); |
| 600 } | 600 } |
| 601 } | 601 } |
| 602 | 602 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 __ RecordWriteContextSlot(scratch0, | 685 __ RecordWriteContextSlot(scratch0, |
| 686 location.offset(), | 686 location.offset(), |
| 687 src, | 687 src, |
| 688 scratch1, | 688 scratch1, |
| 689 kRAHasBeenSaved, | 689 kRAHasBeenSaved, |
| 690 kDontSaveFPRegs); | 690 kDontSaveFPRegs); |
| 691 } | 691 } |
| 692 } | 692 } |
| 693 | 693 |
| 694 | 694 |
| 695 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state, | 695 void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, |
| 696 bool should_normalize, | 696 bool should_normalize, |
| 697 Label* if_true, | 697 Label* if_true, |
| 698 Label* if_false) { | 698 Label* if_false) { |
| 699 // Only prepare for bailouts before splits if we're in a test | 699 // Only prepare for bailouts before splits if we're in a test |
| 700 // context. Otherwise, we let the Visit function deal with the | 700 // context. Otherwise, we let the Visit function deal with the |
| 701 // preparation to avoid preparing with the same AST id twice. | 701 // preparation to avoid preparing with the same AST id twice. |
| 702 if (!context()->IsTest() || !info_->IsOptimizable()) return; | 702 if (!context()->IsTest() || !info_->IsOptimizable()) return; |
| 703 | 703 |
| 704 Label skip; | 704 Label skip; |
| 705 if (should_normalize) __ Branch(&skip); | 705 if (should_normalize) __ Branch(&skip); |
| 706 | 706 PrepareForBailout(expr, TOS_REG); |
| 707 ForwardBailoutStack* current = forward_bailout_stack_; | |
| 708 while (current != NULL) { | |
| 709 PrepareForBailout(current->expr(), state); | |
| 710 current = current->parent(); | |
| 711 } | |
| 712 | |
| 713 if (should_normalize) { | 707 if (should_normalize) { |
| 714 __ LoadRoot(t0, Heap::kTrueValueRootIndex); | 708 __ LoadRoot(t0, Heap::kTrueValueRootIndex); |
| 715 Split(eq, a0, Operand(t0), if_true, if_false, NULL); | 709 Split(eq, a0, Operand(t0), if_true, if_false, NULL); |
| 716 __ bind(&skip); | 710 __ bind(&skip); |
| 717 } | 711 } |
| 718 } | 712 } |
| 719 | 713 |
| 720 | 714 |
| 721 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, | 715 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, |
| 722 VariableMode mode, | 716 VariableMode mode, |
| (...skipping 1671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2394 __ li(a0, Operand(arg_count)); | 2388 __ li(a0, Operand(arg_count)); |
| 2395 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); | 2389 __ lw(a1, MemOperand(sp, arg_count * kPointerSize)); |
| 2396 | 2390 |
| 2397 Handle<Code> construct_builtin = | 2391 Handle<Code> construct_builtin = |
| 2398 isolate()->builtins()->JSConstructCall(); | 2392 isolate()->builtins()->JSConstructCall(); |
| 2399 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 2393 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
| 2400 context()->Plug(v0); | 2394 context()->Plug(v0); |
| 2401 } | 2395 } |
| 2402 | 2396 |
| 2403 | 2397 |
| 2404 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { | 2398 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 2399 ZoneList<Expression*>* args = expr->arguments(); |
| 2405 ASSERT(args->length() == 1); | 2400 ASSERT(args->length() == 1); |
| 2406 | 2401 |
| 2407 VisitForAccumulatorValue(args->at(0)); | 2402 VisitForAccumulatorValue(args->at(0)); |
| 2408 | 2403 |
| 2409 Label materialize_true, materialize_false; | 2404 Label materialize_true, materialize_false; |
| 2410 Label* if_true = NULL; | 2405 Label* if_true = NULL; |
| 2411 Label* if_false = NULL; | 2406 Label* if_false = NULL; |
| 2412 Label* fall_through = NULL; | 2407 Label* fall_through = NULL; |
| 2413 context()->PrepareTest(&materialize_true, &materialize_false, | 2408 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2414 &if_true, &if_false, &fall_through); | 2409 &if_true, &if_false, &fall_through); |
| 2415 | 2410 |
| 2416 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 2411 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2417 __ And(t0, v0, Operand(kSmiTagMask)); | 2412 __ And(t0, v0, Operand(kSmiTagMask)); |
| 2418 Split(eq, t0, Operand(zero_reg), if_true, if_false, fall_through); | 2413 Split(eq, t0, Operand(zero_reg), if_true, if_false, fall_through); |
| 2419 | 2414 |
| 2420 context()->Plug(if_true, if_false); | 2415 context()->Plug(if_true, if_false); |
| 2421 } | 2416 } |
| 2422 | 2417 |
| 2423 | 2418 |
| 2424 void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) { | 2419 void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { |
| 2420 ZoneList<Expression*>* args = expr->arguments(); |
| 2425 ASSERT(args->length() == 1); | 2421 ASSERT(args->length() == 1); |
| 2426 | 2422 |
| 2427 VisitForAccumulatorValue(args->at(0)); | 2423 VisitForAccumulatorValue(args->at(0)); |
| 2428 | 2424 |
| 2429 Label materialize_true, materialize_false; | 2425 Label materialize_true, materialize_false; |
| 2430 Label* if_true = NULL; | 2426 Label* if_true = NULL; |
| 2431 Label* if_false = NULL; | 2427 Label* if_false = NULL; |
| 2432 Label* fall_through = NULL; | 2428 Label* fall_through = NULL; |
| 2433 context()->PrepareTest(&materialize_true, &materialize_false, | 2429 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2434 &if_true, &if_false, &fall_through); | 2430 &if_true, &if_false, &fall_through); |
| 2435 | 2431 |
| 2436 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 2432 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2437 __ And(at, v0, Operand(kSmiTagMask | 0x80000000)); | 2433 __ And(at, v0, Operand(kSmiTagMask | 0x80000000)); |
| 2438 Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through); | 2434 Split(eq, at, Operand(zero_reg), if_true, if_false, fall_through); |
| 2439 | 2435 |
| 2440 context()->Plug(if_true, if_false); | 2436 context()->Plug(if_true, if_false); |
| 2441 } | 2437 } |
| 2442 | 2438 |
| 2443 | 2439 |
| 2444 void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) { | 2440 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) { |
| 2441 ZoneList<Expression*>* args = expr->arguments(); |
| 2445 ASSERT(args->length() == 1); | 2442 ASSERT(args->length() == 1); |
| 2446 | 2443 |
| 2447 VisitForAccumulatorValue(args->at(0)); | 2444 VisitForAccumulatorValue(args->at(0)); |
| 2448 | 2445 |
| 2449 Label materialize_true, materialize_false; | 2446 Label materialize_true, materialize_false; |
| 2450 Label* if_true = NULL; | 2447 Label* if_true = NULL; |
| 2451 Label* if_false = NULL; | 2448 Label* if_false = NULL; |
| 2452 Label* fall_through = NULL; | 2449 Label* fall_through = NULL; |
| 2453 context()->PrepareTest(&materialize_true, &materialize_false, | 2450 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2454 &if_true, &if_false, &fall_through); | 2451 &if_true, &if_false, &fall_through); |
| 2455 | 2452 |
| 2456 __ JumpIfSmi(v0, if_false); | 2453 __ JumpIfSmi(v0, if_false); |
| 2457 __ LoadRoot(at, Heap::kNullValueRootIndex); | 2454 __ LoadRoot(at, Heap::kNullValueRootIndex); |
| 2458 __ Branch(if_true, eq, v0, Operand(at)); | 2455 __ Branch(if_true, eq, v0, Operand(at)); |
| 2459 __ lw(a2, FieldMemOperand(v0, HeapObject::kMapOffset)); | 2456 __ lw(a2, FieldMemOperand(v0, HeapObject::kMapOffset)); |
| 2460 // Undetectable objects behave like undefined when tested with typeof. | 2457 // Undetectable objects behave like undefined when tested with typeof. |
| 2461 __ lbu(a1, FieldMemOperand(a2, Map::kBitFieldOffset)); | 2458 __ lbu(a1, FieldMemOperand(a2, Map::kBitFieldOffset)); |
| 2462 __ And(at, a1, Operand(1 << Map::kIsUndetectable)); | 2459 __ And(at, a1, Operand(1 << Map::kIsUndetectable)); |
| 2463 __ Branch(if_false, ne, at, Operand(zero_reg)); | 2460 __ Branch(if_false, ne, at, Operand(zero_reg)); |
| 2464 __ lbu(a1, FieldMemOperand(a2, Map::kInstanceTypeOffset)); | 2461 __ lbu(a1, FieldMemOperand(a2, Map::kInstanceTypeOffset)); |
| 2465 __ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2462 __ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 2466 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 2463 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2467 Split(le, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE), | 2464 Split(le, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE), |
| 2468 if_true, if_false, fall_through); | 2465 if_true, if_false, fall_through); |
| 2469 | 2466 |
| 2470 context()->Plug(if_true, if_false); | 2467 context()->Plug(if_true, if_false); |
| 2471 } | 2468 } |
| 2472 | 2469 |
| 2473 | 2470 |
| 2474 void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) { | 2471 void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { |
| 2472 ZoneList<Expression*>* args = expr->arguments(); |
| 2475 ASSERT(args->length() == 1); | 2473 ASSERT(args->length() == 1); |
| 2476 | 2474 |
| 2477 VisitForAccumulatorValue(args->at(0)); | 2475 VisitForAccumulatorValue(args->at(0)); |
| 2478 | 2476 |
| 2479 Label materialize_true, materialize_false; | 2477 Label materialize_true, materialize_false; |
| 2480 Label* if_true = NULL; | 2478 Label* if_true = NULL; |
| 2481 Label* if_false = NULL; | 2479 Label* if_false = NULL; |
| 2482 Label* fall_through = NULL; | 2480 Label* fall_through = NULL; |
| 2483 context()->PrepareTest(&materialize_true, &materialize_false, | 2481 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2484 &if_true, &if_false, &fall_through); | 2482 &if_true, &if_false, &fall_through); |
| 2485 | 2483 |
| 2486 __ JumpIfSmi(v0, if_false); | 2484 __ JumpIfSmi(v0, if_false); |
| 2487 __ GetObjectType(v0, a1, a1); | 2485 __ GetObjectType(v0, a1, a1); |
| 2488 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 2486 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2489 Split(ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE), | 2487 Split(ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE), |
| 2490 if_true, if_false, fall_through); | 2488 if_true, if_false, fall_through); |
| 2491 | 2489 |
| 2492 context()->Plug(if_true, if_false); | 2490 context()->Plug(if_true, if_false); |
| 2493 } | 2491 } |
| 2494 | 2492 |
| 2495 | 2493 |
| 2496 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { | 2494 void FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) { |
| 2495 ZoneList<Expression*>* args = expr->arguments(); |
| 2497 ASSERT(args->length() == 1); | 2496 ASSERT(args->length() == 1); |
| 2498 | 2497 |
| 2499 VisitForAccumulatorValue(args->at(0)); | 2498 VisitForAccumulatorValue(args->at(0)); |
| 2500 | 2499 |
| 2501 Label materialize_true, materialize_false; | 2500 Label materialize_true, materialize_false; |
| 2502 Label* if_true = NULL; | 2501 Label* if_true = NULL; |
| 2503 Label* if_false = NULL; | 2502 Label* if_false = NULL; |
| 2504 Label* fall_through = NULL; | 2503 Label* fall_through = NULL; |
| 2505 context()->PrepareTest(&materialize_true, &materialize_false, | 2504 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2506 &if_true, &if_false, &fall_through); | 2505 &if_true, &if_false, &fall_through); |
| 2507 | 2506 |
| 2508 __ JumpIfSmi(v0, if_false); | 2507 __ JumpIfSmi(v0, if_false); |
| 2509 __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); | 2508 __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); |
| 2510 __ lbu(a1, FieldMemOperand(a1, Map::kBitFieldOffset)); | 2509 __ lbu(a1, FieldMemOperand(a1, Map::kBitFieldOffset)); |
| 2511 __ And(at, a1, Operand(1 << Map::kIsUndetectable)); | 2510 __ And(at, a1, Operand(1 << Map::kIsUndetectable)); |
| 2512 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 2511 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2513 Split(ne, at, Operand(zero_reg), if_true, if_false, fall_through); | 2512 Split(ne, at, Operand(zero_reg), if_true, if_false, fall_through); |
| 2514 | 2513 |
| 2515 context()->Plug(if_true, if_false); | 2514 context()->Plug(if_true, if_false); |
| 2516 } | 2515 } |
| 2517 | 2516 |
| 2518 | 2517 |
| 2519 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( | 2518 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( |
| 2520 ZoneList<Expression*>* args) { | 2519 CallRuntime* expr) { |
| 2521 | 2520 ZoneList<Expression*>* args = expr->arguments(); |
| 2522 ASSERT(args->length() == 1); | 2521 ASSERT(args->length() == 1); |
| 2523 | 2522 |
| 2524 VisitForAccumulatorValue(args->at(0)); | 2523 VisitForAccumulatorValue(args->at(0)); |
| 2525 | 2524 |
| 2526 Label materialize_true, materialize_false; | 2525 Label materialize_true, materialize_false; |
| 2527 Label* if_true = NULL; | 2526 Label* if_true = NULL; |
| 2528 Label* if_false = NULL; | 2527 Label* if_false = NULL; |
| 2529 Label* fall_through = NULL; | 2528 Label* fall_through = NULL; |
| 2530 context()->PrepareTest(&materialize_true, &materialize_false, | 2529 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2531 &if_true, &if_false, &fall_through); | 2530 &if_true, &if_false, &fall_through); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2587 __ lw(a3, ContextOperand(a3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); | 2586 __ lw(a3, ContextOperand(a3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); |
| 2588 __ Branch(if_false, ne, a2, Operand(a3)); | 2587 __ Branch(if_false, ne, a2, Operand(a3)); |
| 2589 | 2588 |
| 2590 // Set the bit in the map to indicate that it has been checked safe for | 2589 // Set the bit in the map to indicate that it has been checked safe for |
| 2591 // default valueOf and set true result. | 2590 // default valueOf and set true result. |
| 2592 __ lbu(a2, FieldMemOperand(a1, Map::kBitField2Offset)); | 2591 __ lbu(a2, FieldMemOperand(a1, Map::kBitField2Offset)); |
| 2593 __ Or(a2, a2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); | 2592 __ Or(a2, a2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); |
| 2594 __ sb(a2, FieldMemOperand(a1, Map::kBitField2Offset)); | 2593 __ sb(a2, FieldMemOperand(a1, Map::kBitField2Offset)); |
| 2595 __ jmp(if_true); | 2594 __ jmp(if_true); |
| 2596 | 2595 |
| 2597 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 2596 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2598 context()->Plug(if_true, if_false); | 2597 context()->Plug(if_true, if_false); |
| 2599 } | 2598 } |
| 2600 | 2599 |
| 2601 | 2600 |
| 2602 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { | 2601 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) { |
| 2602 ZoneList<Expression*>* args = expr->arguments(); |
| 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(true, if_true, if_false); | 2616 PrepareForBailoutBeforeSplit(expr, 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(CallRuntime* expr) { |
| 2625 ZoneList<Expression*>* args = expr->arguments(); |
| 2625 ASSERT(args->length() == 1); | 2626 ASSERT(args->length() == 1); |
| 2626 | 2627 |
| 2627 VisitForAccumulatorValue(args->at(0)); | 2628 VisitForAccumulatorValue(args->at(0)); |
| 2628 | 2629 |
| 2629 Label materialize_true, materialize_false; | 2630 Label materialize_true, materialize_false; |
| 2630 Label* if_true = NULL; | 2631 Label* if_true = NULL; |
| 2631 Label* if_false = NULL; | 2632 Label* if_false = NULL; |
| 2632 Label* fall_through = NULL; | 2633 Label* fall_through = NULL; |
| 2633 context()->PrepareTest(&materialize_true, &materialize_false, | 2634 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2634 &if_true, &if_false, &fall_through); | 2635 &if_true, &if_false, &fall_through); |
| 2635 | 2636 |
| 2636 __ JumpIfSmi(v0, if_false); | 2637 __ JumpIfSmi(v0, if_false); |
| 2637 __ GetObjectType(v0, a1, a1); | 2638 __ GetObjectType(v0, a1, a1); |
| 2638 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 2639 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2639 Split(eq, a1, Operand(JS_ARRAY_TYPE), | 2640 Split(eq, a1, Operand(JS_ARRAY_TYPE), |
| 2640 if_true, if_false, fall_through); | 2641 if_true, if_false, fall_through); |
| 2641 | 2642 |
| 2642 context()->Plug(if_true, if_false); | 2643 context()->Plug(if_true, if_false); |
| 2643 } | 2644 } |
| 2644 | 2645 |
| 2645 | 2646 |
| 2646 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { | 2647 void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) { |
| 2648 ZoneList<Expression*>* args = expr->arguments(); |
| 2647 ASSERT(args->length() == 1); | 2649 ASSERT(args->length() == 1); |
| 2648 | 2650 |
| 2649 VisitForAccumulatorValue(args->at(0)); | 2651 VisitForAccumulatorValue(args->at(0)); |
| 2650 | 2652 |
| 2651 Label materialize_true, materialize_false; | 2653 Label materialize_true, materialize_false; |
| 2652 Label* if_true = NULL; | 2654 Label* if_true = NULL; |
| 2653 Label* if_false = NULL; | 2655 Label* if_false = NULL; |
| 2654 Label* fall_through = NULL; | 2656 Label* fall_through = NULL; |
| 2655 context()->PrepareTest(&materialize_true, &materialize_false, | 2657 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2656 &if_true, &if_false, &fall_through); | 2658 &if_true, &if_false, &fall_through); |
| 2657 | 2659 |
| 2658 __ JumpIfSmi(v0, if_false); | 2660 __ JumpIfSmi(v0, if_false); |
| 2659 __ GetObjectType(v0, a1, a1); | 2661 __ GetObjectType(v0, a1, a1); |
| 2660 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 2662 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2661 Split(eq, a1, Operand(JS_REGEXP_TYPE), if_true, if_false, fall_through); | 2663 Split(eq, a1, Operand(JS_REGEXP_TYPE), if_true, if_false, fall_through); |
| 2662 | 2664 |
| 2663 context()->Plug(if_true, if_false); | 2665 context()->Plug(if_true, if_false); |
| 2664 } | 2666 } |
| 2665 | 2667 |
| 2666 | 2668 |
| 2667 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { | 2669 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) { |
| 2668 ASSERT(args->length() == 0); | 2670 ASSERT(expr->arguments()->length() == 0); |
| 2669 | 2671 |
| 2670 Label materialize_true, materialize_false; | 2672 Label materialize_true, materialize_false; |
| 2671 Label* if_true = NULL; | 2673 Label* if_true = NULL; |
| 2672 Label* if_false = NULL; | 2674 Label* if_false = NULL; |
| 2673 Label* fall_through = NULL; | 2675 Label* fall_through = NULL; |
| 2674 context()->PrepareTest(&materialize_true, &materialize_false, | 2676 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2675 &if_true, &if_false, &fall_through); | 2677 &if_true, &if_false, &fall_through); |
| 2676 | 2678 |
| 2677 // Get the frame pointer for the calling frame. | 2679 // Get the frame pointer for the calling frame. |
| 2678 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 2680 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 2679 | 2681 |
| 2680 // Skip the arguments adaptor frame if it exists. | 2682 // Skip the arguments adaptor frame if it exists. |
| 2681 Label check_frame_marker; | 2683 Label check_frame_marker; |
| 2682 __ lw(a1, MemOperand(a2, StandardFrameConstants::kContextOffset)); | 2684 __ lw(a1, MemOperand(a2, StandardFrameConstants::kContextOffset)); |
| 2683 __ Branch(&check_frame_marker, ne, | 2685 __ Branch(&check_frame_marker, ne, |
| 2684 a1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 2686 a1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 2685 __ lw(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset)); | 2687 __ lw(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset)); |
| 2686 | 2688 |
| 2687 // Check the marker in the calling frame. | 2689 // Check the marker in the calling frame. |
| 2688 __ bind(&check_frame_marker); | 2690 __ bind(&check_frame_marker); |
| 2689 __ lw(a1, MemOperand(a2, StandardFrameConstants::kMarkerOffset)); | 2691 __ lw(a1, MemOperand(a2, StandardFrameConstants::kMarkerOffset)); |
| 2690 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 2692 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2691 Split(eq, a1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)), | 2693 Split(eq, a1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)), |
| 2692 if_true, if_false, fall_through); | 2694 if_true, if_false, fall_through); |
| 2693 | 2695 |
| 2694 context()->Plug(if_true, if_false); | 2696 context()->Plug(if_true, if_false); |
| 2695 } | 2697 } |
| 2696 | 2698 |
| 2697 | 2699 |
| 2698 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { | 2700 void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) { |
| 2701 ZoneList<Expression*>* args = expr->arguments(); |
| 2699 ASSERT(args->length() == 2); | 2702 ASSERT(args->length() == 2); |
| 2700 | 2703 |
| 2701 // Load the two objects into registers and perform the comparison. | 2704 // Load the two objects into registers and perform the comparison. |
| 2702 VisitForStackValue(args->at(0)); | 2705 VisitForStackValue(args->at(0)); |
| 2703 VisitForAccumulatorValue(args->at(1)); | 2706 VisitForAccumulatorValue(args->at(1)); |
| 2704 | 2707 |
| 2705 Label materialize_true, materialize_false; | 2708 Label materialize_true, materialize_false; |
| 2706 Label* if_true = NULL; | 2709 Label* if_true = NULL; |
| 2707 Label* if_false = NULL; | 2710 Label* if_false = NULL; |
| 2708 Label* fall_through = NULL; | 2711 Label* fall_through = NULL; |
| 2709 context()->PrepareTest(&materialize_true, &materialize_false, | 2712 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2710 &if_true, &if_false, &fall_through); | 2713 &if_true, &if_false, &fall_through); |
| 2711 | 2714 |
| 2712 __ pop(a1); | 2715 __ pop(a1); |
| 2713 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 2716 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2714 Split(eq, v0, Operand(a1), if_true, if_false, fall_through); | 2717 Split(eq, v0, Operand(a1), if_true, if_false, fall_through); |
| 2715 | 2718 |
| 2716 context()->Plug(if_true, if_false); | 2719 context()->Plug(if_true, if_false); |
| 2717 } | 2720 } |
| 2718 | 2721 |
| 2719 | 2722 |
| 2720 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { | 2723 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { |
| 2724 ZoneList<Expression*>* args = expr->arguments(); |
| 2721 ASSERT(args->length() == 1); | 2725 ASSERT(args->length() == 1); |
| 2722 | 2726 |
| 2723 // ArgumentsAccessStub expects the key in a1 and the formal | 2727 // ArgumentsAccessStub expects the key in a1 and the formal |
| 2724 // parameter count in a0. | 2728 // parameter count in a0. |
| 2725 VisitForAccumulatorValue(args->at(0)); | 2729 VisitForAccumulatorValue(args->at(0)); |
| 2726 __ mov(a1, v0); | 2730 __ mov(a1, v0); |
| 2727 __ li(a0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); | 2731 __ li(a0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); |
| 2728 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | 2732 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); |
| 2729 __ CallStub(&stub); | 2733 __ CallStub(&stub); |
| 2730 context()->Plug(v0); | 2734 context()->Plug(v0); |
| 2731 } | 2735 } |
| 2732 | 2736 |
| 2733 | 2737 |
| 2734 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { | 2738 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { |
| 2735 ASSERT(args->length() == 0); | 2739 ASSERT(expr->arguments()->length() == 0); |
| 2736 | |
| 2737 Label exit; | 2740 Label exit; |
| 2738 // Get the number of formal parameters. | 2741 // Get the number of formal parameters. |
| 2739 __ li(v0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); | 2742 __ li(v0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); |
| 2740 | 2743 |
| 2741 // Check if the calling frame is an arguments adaptor frame. | 2744 // Check if the calling frame is an arguments adaptor frame. |
| 2742 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 2745 __ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 2743 __ lw(a3, MemOperand(a2, StandardFrameConstants::kContextOffset)); | 2746 __ lw(a3, MemOperand(a2, StandardFrameConstants::kContextOffset)); |
| 2744 __ Branch(&exit, ne, a3, | 2747 __ Branch(&exit, ne, a3, |
| 2745 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 2748 Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 2746 | 2749 |
| 2747 // Arguments adaptor case: Read the arguments length from the | 2750 // Arguments adaptor case: Read the arguments length from the |
| 2748 // adaptor frame. | 2751 // adaptor frame. |
| 2749 __ lw(v0, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2752 __ lw(v0, MemOperand(a2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 2750 | 2753 |
| 2751 __ bind(&exit); | 2754 __ bind(&exit); |
| 2752 context()->Plug(v0); | 2755 context()->Plug(v0); |
| 2753 } | 2756 } |
| 2754 | 2757 |
| 2755 | 2758 |
| 2756 void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) { | 2759 void FullCodeGenerator::EmitClassOf(CallRuntime* expr) { |
| 2760 ZoneList<Expression*>* args = expr->arguments(); |
| 2757 ASSERT(args->length() == 1); | 2761 ASSERT(args->length() == 1); |
| 2758 Label done, null, function, non_function_constructor; | 2762 Label done, null, function, non_function_constructor; |
| 2759 | 2763 |
| 2760 VisitForAccumulatorValue(args->at(0)); | 2764 VisitForAccumulatorValue(args->at(0)); |
| 2761 | 2765 |
| 2762 // If the object is a smi, we return null. | 2766 // If the object is a smi, we return null. |
| 2763 __ JumpIfSmi(v0, &null); | 2767 __ JumpIfSmi(v0, &null); |
| 2764 | 2768 |
| 2765 // Check that the object is a JS object but take special care of JS | 2769 // Check that the object is a JS object but take special care of JS |
| 2766 // functions to make sure they have 'Function' as their class. | 2770 // functions to make sure they have 'Function' as their class. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2805 __ bind(&null); | 2809 __ bind(&null); |
| 2806 __ LoadRoot(v0, Heap::kNullValueRootIndex); | 2810 __ LoadRoot(v0, Heap::kNullValueRootIndex); |
| 2807 | 2811 |
| 2808 // All done. | 2812 // All done. |
| 2809 __ bind(&done); | 2813 __ bind(&done); |
| 2810 | 2814 |
| 2811 context()->Plug(v0); | 2815 context()->Plug(v0); |
| 2812 } | 2816 } |
| 2813 | 2817 |
| 2814 | 2818 |
| 2815 void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) { | 2819 void FullCodeGenerator::EmitLog(CallRuntime* expr) { |
| 2816 // Conditionally generate a log call. | 2820 // Conditionally generate a log call. |
| 2817 // Args: | 2821 // Args: |
| 2818 // 0 (literal string): The type of logging (corresponds to the flags). | 2822 // 0 (literal string): The type of logging (corresponds to the flags). |
| 2819 // This is used to determine whether or not to generate the log call. | 2823 // This is used to determine whether or not to generate the log call. |
| 2820 // 1 (string): Format string. Access the string at argument index 2 | 2824 // 1 (string): Format string. Access the string at argument index 2 |
| 2821 // with '%2s' (see Logger::LogRuntime for all the formats). | 2825 // with '%2s' (see Logger::LogRuntime for all the formats). |
| 2822 // 2 (array): Arguments to the format string. | 2826 // 2 (array): Arguments to the format string. |
| 2827 ZoneList<Expression*>* args = expr->arguments(); |
| 2823 ASSERT_EQ(args->length(), 3); | 2828 ASSERT_EQ(args->length(), 3); |
| 2824 if (CodeGenerator::ShouldGenerateLog(args->at(0))) { | 2829 if (CodeGenerator::ShouldGenerateLog(args->at(0))) { |
| 2825 VisitForStackValue(args->at(1)); | 2830 VisitForStackValue(args->at(1)); |
| 2826 VisitForStackValue(args->at(2)); | 2831 VisitForStackValue(args->at(2)); |
| 2827 __ CallRuntime(Runtime::kLog, 2); | 2832 __ CallRuntime(Runtime::kLog, 2); |
| 2828 } | 2833 } |
| 2829 | 2834 |
| 2830 // Finally, we're expected to leave a value on the top of the stack. | 2835 // Finally, we're expected to leave a value on the top of the stack. |
| 2831 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 2836 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
| 2832 context()->Plug(v0); | 2837 context()->Plug(v0); |
| 2833 } | 2838 } |
| 2834 | 2839 |
| 2835 | 2840 |
| 2836 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { | 2841 void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) { |
| 2837 ASSERT(args->length() == 0); | 2842 ASSERT(expr->arguments()->length() == 0); |
| 2838 | |
| 2839 Label slow_allocate_heapnumber; | 2843 Label slow_allocate_heapnumber; |
| 2840 Label heapnumber_allocated; | 2844 Label heapnumber_allocated; |
| 2841 | 2845 |
| 2842 // Save the new heap number in callee-saved register s0, since | 2846 // Save the new heap number in callee-saved register s0, since |
| 2843 // we call out to external C code below. | 2847 // we call out to external C code below. |
| 2844 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); | 2848 __ LoadRoot(t6, Heap::kHeapNumberMapRootIndex); |
| 2845 __ AllocateHeapNumber(s0, a1, a2, t6, &slow_allocate_heapnumber); | 2849 __ AllocateHeapNumber(s0, a1, a2, t6, &slow_allocate_heapnumber); |
| 2846 __ jmp(&heapnumber_allocated); | 2850 __ jmp(&heapnumber_allocated); |
| 2847 | 2851 |
| 2848 __ bind(&slow_allocate_heapnumber); | 2852 __ bind(&slow_allocate_heapnumber); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2879 __ lw(a1, ContextOperand(cp, Context::GLOBAL_INDEX)); | 2883 __ lw(a1, ContextOperand(cp, Context::GLOBAL_INDEX)); |
| 2880 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalContextOffset)); | 2884 __ lw(a1, FieldMemOperand(a1, GlobalObject::kGlobalContextOffset)); |
| 2881 __ CallCFunction( | 2885 __ CallCFunction( |
| 2882 ExternalReference::fill_heap_number_with_random_function(isolate()), 2); | 2886 ExternalReference::fill_heap_number_with_random_function(isolate()), 2); |
| 2883 } | 2887 } |
| 2884 | 2888 |
| 2885 context()->Plug(v0); | 2889 context()->Plug(v0); |
| 2886 } | 2890 } |
| 2887 | 2891 |
| 2888 | 2892 |
| 2889 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) { | 2893 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 2890 // Load the arguments on the stack and call the stub. | 2894 // Load the arguments on the stack and call the stub. |
| 2891 SubStringStub stub; | 2895 SubStringStub stub; |
| 2896 ZoneList<Expression*>* args = expr->arguments(); |
| 2892 ASSERT(args->length() == 3); | 2897 ASSERT(args->length() == 3); |
| 2893 VisitForStackValue(args->at(0)); | 2898 VisitForStackValue(args->at(0)); |
| 2894 VisitForStackValue(args->at(1)); | 2899 VisitForStackValue(args->at(1)); |
| 2895 VisitForStackValue(args->at(2)); | 2900 VisitForStackValue(args->at(2)); |
| 2896 __ CallStub(&stub); | 2901 __ CallStub(&stub); |
| 2897 context()->Plug(v0); | 2902 context()->Plug(v0); |
| 2898 } | 2903 } |
| 2899 | 2904 |
| 2900 | 2905 |
| 2901 void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) { | 2906 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 2902 // Load the arguments on the stack and call the stub. | 2907 // Load the arguments on the stack and call the stub. |
| 2903 RegExpExecStub stub; | 2908 RegExpExecStub stub; |
| 2909 ZoneList<Expression*>* args = expr->arguments(); |
| 2904 ASSERT(args->length() == 4); | 2910 ASSERT(args->length() == 4); |
| 2905 VisitForStackValue(args->at(0)); | 2911 VisitForStackValue(args->at(0)); |
| 2906 VisitForStackValue(args->at(1)); | 2912 VisitForStackValue(args->at(1)); |
| 2907 VisitForStackValue(args->at(2)); | 2913 VisitForStackValue(args->at(2)); |
| 2908 VisitForStackValue(args->at(3)); | 2914 VisitForStackValue(args->at(3)); |
| 2909 __ CallStub(&stub); | 2915 __ CallStub(&stub); |
| 2910 context()->Plug(v0); | 2916 context()->Plug(v0); |
| 2911 } | 2917 } |
| 2912 | 2918 |
| 2913 | 2919 |
| 2914 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { | 2920 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
| 2921 ZoneList<Expression*>* args = expr->arguments(); |
| 2915 ASSERT(args->length() == 1); | 2922 ASSERT(args->length() == 1); |
| 2916 | 2923 |
| 2917 VisitForAccumulatorValue(args->at(0)); // Load the object. | 2924 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 2918 | 2925 |
| 2919 Label done; | 2926 Label done; |
| 2920 // If the object is a smi return the object. | 2927 // If the object is a smi return the object. |
| 2921 __ JumpIfSmi(v0, &done); | 2928 __ JumpIfSmi(v0, &done); |
| 2922 // If the object is not a value type, return the object. | 2929 // If the object is not a value type, return the object. |
| 2923 __ GetObjectType(v0, a1, a1); | 2930 __ GetObjectType(v0, a1, a1); |
| 2924 __ Branch(&done, ne, a1, Operand(JS_VALUE_TYPE)); | 2931 __ Branch(&done, ne, a1, Operand(JS_VALUE_TYPE)); |
| 2925 | 2932 |
| 2926 __ lw(v0, FieldMemOperand(v0, JSValue::kValueOffset)); | 2933 __ lw(v0, FieldMemOperand(v0, JSValue::kValueOffset)); |
| 2927 | 2934 |
| 2928 __ bind(&done); | 2935 __ bind(&done); |
| 2929 context()->Plug(v0); | 2936 context()->Plug(v0); |
| 2930 } | 2937 } |
| 2931 | 2938 |
| 2932 | 2939 |
| 2933 void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) { | 2940 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 2934 // Load the arguments on the stack and call the runtime function. | 2941 // Load the arguments on the stack and call the runtime function. |
| 2942 ZoneList<Expression*>* args = expr->arguments(); |
| 2935 ASSERT(args->length() == 2); | 2943 ASSERT(args->length() == 2); |
| 2936 VisitForStackValue(args->at(0)); | 2944 VisitForStackValue(args->at(0)); |
| 2937 VisitForStackValue(args->at(1)); | 2945 VisitForStackValue(args->at(1)); |
| 2938 MathPowStub stub; | 2946 MathPowStub stub; |
| 2939 __ CallStub(&stub); | 2947 __ CallStub(&stub); |
| 2940 context()->Plug(v0); | 2948 context()->Plug(v0); |
| 2941 } | 2949 } |
| 2942 | 2950 |
| 2943 | 2951 |
| 2944 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { | 2952 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 2953 ZoneList<Expression*>* args = expr->arguments(); |
| 2945 ASSERT(args->length() == 2); | 2954 ASSERT(args->length() == 2); |
| 2946 | 2955 |
| 2947 VisitForStackValue(args->at(0)); // Load the object. | 2956 VisitForStackValue(args->at(0)); // Load the object. |
| 2948 VisitForAccumulatorValue(args->at(1)); // Load the value. | 2957 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| 2949 __ pop(a1); // v0 = value. a1 = object. | 2958 __ pop(a1); // v0 = value. a1 = object. |
| 2950 | 2959 |
| 2951 Label done; | 2960 Label done; |
| 2952 // If the object is a smi, return the value. | 2961 // If the object is a smi, return the value. |
| 2953 __ JumpIfSmi(a1, &done); | 2962 __ JumpIfSmi(a1, &done); |
| 2954 | 2963 |
| 2955 // If the object is not a value type, return the value. | 2964 // If the object is not a value type, return the value. |
| 2956 __ GetObjectType(a1, a2, a2); | 2965 __ GetObjectType(a1, a2, a2); |
| 2957 __ Branch(&done, ne, a2, Operand(JS_VALUE_TYPE)); | 2966 __ Branch(&done, ne, a2, Operand(JS_VALUE_TYPE)); |
| 2958 | 2967 |
| 2959 // Store the value. | 2968 // Store the value. |
| 2960 __ sw(v0, FieldMemOperand(a1, JSValue::kValueOffset)); | 2969 __ sw(v0, FieldMemOperand(a1, JSValue::kValueOffset)); |
| 2961 // Update the write barrier. Save the value as it will be | 2970 // Update the write barrier. Save the value as it will be |
| 2962 // overwritten by the write barrier code and is needed afterward. | 2971 // overwritten by the write barrier code and is needed afterward. |
| 2963 __ mov(a2, v0); | 2972 __ mov(a2, v0); |
| 2964 __ RecordWriteField( | 2973 __ RecordWriteField( |
| 2965 a1, JSValue::kValueOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); | 2974 a1, JSValue::kValueOffset, a2, a3, kRAHasBeenSaved, kDontSaveFPRegs); |
| 2966 | 2975 |
| 2967 __ bind(&done); | 2976 __ bind(&done); |
| 2968 context()->Plug(v0); | 2977 context()->Plug(v0); |
| 2969 } | 2978 } |
| 2970 | 2979 |
| 2971 | 2980 |
| 2972 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { | 2981 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 2982 ZoneList<Expression*>* args = expr->arguments(); |
| 2973 ASSERT_EQ(args->length(), 1); | 2983 ASSERT_EQ(args->length(), 1); |
| 2974 | 2984 |
| 2975 // Load the argument on the stack and call the stub. | 2985 // Load the argument on the stack and call the stub. |
| 2976 VisitForStackValue(args->at(0)); | 2986 VisitForStackValue(args->at(0)); |
| 2977 | 2987 |
| 2978 NumberToStringStub stub; | 2988 NumberToStringStub stub; |
| 2979 __ CallStub(&stub); | 2989 __ CallStub(&stub); |
| 2980 context()->Plug(v0); | 2990 context()->Plug(v0); |
| 2981 } | 2991 } |
| 2982 | 2992 |
| 2983 | 2993 |
| 2984 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) { | 2994 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
| 2995 ZoneList<Expression*>* args = expr->arguments(); |
| 2985 ASSERT(args->length() == 1); | 2996 ASSERT(args->length() == 1); |
| 2986 | 2997 |
| 2987 VisitForAccumulatorValue(args->at(0)); | 2998 VisitForAccumulatorValue(args->at(0)); |
| 2988 | 2999 |
| 2989 Label done; | 3000 Label done; |
| 2990 StringCharFromCodeGenerator generator(v0, a1); | 3001 StringCharFromCodeGenerator generator(v0, a1); |
| 2991 generator.GenerateFast(masm_); | 3002 generator.GenerateFast(masm_); |
| 2992 __ jmp(&done); | 3003 __ jmp(&done); |
| 2993 | 3004 |
| 2994 NopRuntimeCallHelper call_helper; | 3005 NopRuntimeCallHelper call_helper; |
| 2995 generator.GenerateSlow(masm_, call_helper); | 3006 generator.GenerateSlow(masm_, call_helper); |
| 2996 | 3007 |
| 2997 __ bind(&done); | 3008 __ bind(&done); |
| 2998 context()->Plug(a1); | 3009 context()->Plug(a1); |
| 2999 } | 3010 } |
| 3000 | 3011 |
| 3001 | 3012 |
| 3002 void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) { | 3013 void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) { |
| 3014 ZoneList<Expression*>* args = expr->arguments(); |
| 3003 ASSERT(args->length() == 2); | 3015 ASSERT(args->length() == 2); |
| 3004 | 3016 |
| 3005 VisitForStackValue(args->at(0)); | 3017 VisitForStackValue(args->at(0)); |
| 3006 VisitForAccumulatorValue(args->at(1)); | 3018 VisitForAccumulatorValue(args->at(1)); |
| 3007 __ mov(a0, result_register()); | 3019 __ mov(a0, result_register()); |
| 3008 | 3020 |
| 3009 Register object = a1; | 3021 Register object = a1; |
| 3010 Register index = a0; | 3022 Register index = a0; |
| 3011 Register scratch = a2; | 3023 Register scratch = a2; |
| 3012 Register result = v0; | 3024 Register result = v0; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3040 __ jmp(&done); | 3052 __ jmp(&done); |
| 3041 | 3053 |
| 3042 NopRuntimeCallHelper call_helper; | 3054 NopRuntimeCallHelper call_helper; |
| 3043 generator.GenerateSlow(masm_, call_helper); | 3055 generator.GenerateSlow(masm_, call_helper); |
| 3044 | 3056 |
| 3045 __ bind(&done); | 3057 __ bind(&done); |
| 3046 context()->Plug(result); | 3058 context()->Plug(result); |
| 3047 } | 3059 } |
| 3048 | 3060 |
| 3049 | 3061 |
| 3050 void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) { | 3062 void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) { |
| 3063 ZoneList<Expression*>* args = expr->arguments(); |
| 3051 ASSERT(args->length() == 2); | 3064 ASSERT(args->length() == 2); |
| 3052 | 3065 |
| 3053 VisitForStackValue(args->at(0)); | 3066 VisitForStackValue(args->at(0)); |
| 3054 VisitForAccumulatorValue(args->at(1)); | 3067 VisitForAccumulatorValue(args->at(1)); |
| 3055 __ mov(a0, result_register()); | 3068 __ mov(a0, result_register()); |
| 3056 | 3069 |
| 3057 Register object = a1; | 3070 Register object = a1; |
| 3058 Register index = a0; | 3071 Register index = a0; |
| 3059 Register scratch1 = a2; | 3072 Register scratch1 = a2; |
| 3060 Register scratch2 = a3; | 3073 Register scratch2 = a3; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3090 __ jmp(&done); | 3103 __ jmp(&done); |
| 3091 | 3104 |
| 3092 NopRuntimeCallHelper call_helper; | 3105 NopRuntimeCallHelper call_helper; |
| 3093 generator.GenerateSlow(masm_, call_helper); | 3106 generator.GenerateSlow(masm_, call_helper); |
| 3094 | 3107 |
| 3095 __ bind(&done); | 3108 __ bind(&done); |
| 3096 context()->Plug(result); | 3109 context()->Plug(result); |
| 3097 } | 3110 } |
| 3098 | 3111 |
| 3099 | 3112 |
| 3100 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { | 3113 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { |
| 3114 ZoneList<Expression*>* args = expr->arguments(); |
| 3101 ASSERT_EQ(2, args->length()); | 3115 ASSERT_EQ(2, args->length()); |
| 3102 | |
| 3103 VisitForStackValue(args->at(0)); | 3116 VisitForStackValue(args->at(0)); |
| 3104 VisitForStackValue(args->at(1)); | 3117 VisitForStackValue(args->at(1)); |
| 3105 | 3118 |
| 3106 StringAddStub stub(NO_STRING_ADD_FLAGS); | 3119 StringAddStub stub(NO_STRING_ADD_FLAGS); |
| 3107 __ CallStub(&stub); | 3120 __ CallStub(&stub); |
| 3108 context()->Plug(v0); | 3121 context()->Plug(v0); |
| 3109 } | 3122 } |
| 3110 | 3123 |
| 3111 | 3124 |
| 3112 void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) { | 3125 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 3126 ZoneList<Expression*>* args = expr->arguments(); |
| 3113 ASSERT_EQ(2, args->length()); | 3127 ASSERT_EQ(2, args->length()); |
| 3114 | 3128 |
| 3115 VisitForStackValue(args->at(0)); | 3129 VisitForStackValue(args->at(0)); |
| 3116 VisitForStackValue(args->at(1)); | 3130 VisitForStackValue(args->at(1)); |
| 3117 | 3131 |
| 3118 StringCompareStub stub; | 3132 StringCompareStub stub; |
| 3119 __ CallStub(&stub); | 3133 __ CallStub(&stub); |
| 3120 context()->Plug(v0); | 3134 context()->Plug(v0); |
| 3121 } | 3135 } |
| 3122 | 3136 |
| 3123 | 3137 |
| 3124 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { | 3138 void FullCodeGenerator::EmitMathSin(CallRuntime* expr) { |
| 3125 // Load the argument on the stack and call the stub. | 3139 // Load the argument on the stack and call the stub. |
| 3126 TranscendentalCacheStub stub(TranscendentalCache::SIN, | 3140 TranscendentalCacheStub stub(TranscendentalCache::SIN, |
| 3127 TranscendentalCacheStub::TAGGED); | 3141 TranscendentalCacheStub::TAGGED); |
| 3142 ZoneList<Expression*>* args = expr->arguments(); |
| 3128 ASSERT(args->length() == 1); | 3143 ASSERT(args->length() == 1); |
| 3129 VisitForStackValue(args->at(0)); | 3144 VisitForStackValue(args->at(0)); |
| 3130 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos. | 3145 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos. |
| 3131 __ CallStub(&stub); | 3146 __ CallStub(&stub); |
| 3132 context()->Plug(v0); | 3147 context()->Plug(v0); |
| 3133 } | 3148 } |
| 3134 | 3149 |
| 3135 | 3150 |
| 3136 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { | 3151 void FullCodeGenerator::EmitMathCos(CallRuntime* expr) { |
| 3137 // Load the argument on the stack and call the stub. | 3152 // Load the argument on the stack and call the stub. |
| 3138 TranscendentalCacheStub stub(TranscendentalCache::COS, | 3153 TranscendentalCacheStub stub(TranscendentalCache::COS, |
| 3139 TranscendentalCacheStub::TAGGED); | 3154 TranscendentalCacheStub::TAGGED); |
| 3155 ZoneList<Expression*>* args = expr->arguments(); |
| 3140 ASSERT(args->length() == 1); | 3156 ASSERT(args->length() == 1); |
| 3141 VisitForStackValue(args->at(0)); | 3157 VisitForStackValue(args->at(0)); |
| 3142 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos. | 3158 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos. |
| 3143 __ CallStub(&stub); | 3159 __ CallStub(&stub); |
| 3144 context()->Plug(v0); | 3160 context()->Plug(v0); |
| 3145 } | 3161 } |
| 3146 | 3162 |
| 3147 | 3163 |
| 3148 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) { | 3164 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) { |
| 3149 // Load the argument on the stack and call the stub. | 3165 // Load the argument on the stack and call the stub. |
| 3150 TranscendentalCacheStub stub(TranscendentalCache::LOG, | 3166 TranscendentalCacheStub stub(TranscendentalCache::LOG, |
| 3151 TranscendentalCacheStub::TAGGED); | 3167 TranscendentalCacheStub::TAGGED); |
| 3168 ZoneList<Expression*>* args = expr->arguments(); |
| 3152 ASSERT(args->length() == 1); | 3169 ASSERT(args->length() == 1); |
| 3153 VisitForStackValue(args->at(0)); | 3170 VisitForStackValue(args->at(0)); |
| 3154 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos. | 3171 __ mov(a0, result_register()); // Stub requires parameter in a0 and on tos. |
| 3155 __ CallStub(&stub); | 3172 __ CallStub(&stub); |
| 3156 context()->Plug(v0); | 3173 context()->Plug(v0); |
| 3157 } | 3174 } |
| 3158 | 3175 |
| 3159 | 3176 |
| 3160 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { | 3177 void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) { |
| 3161 // Load the argument on the stack and call the runtime function. | 3178 // Load the argument on the stack and call the runtime function. |
| 3179 ZoneList<Expression*>* args = expr->arguments(); |
| 3162 ASSERT(args->length() == 1); | 3180 ASSERT(args->length() == 1); |
| 3163 VisitForStackValue(args->at(0)); | 3181 VisitForStackValue(args->at(0)); |
| 3164 __ CallRuntime(Runtime::kMath_sqrt, 1); | 3182 __ CallRuntime(Runtime::kMath_sqrt, 1); |
| 3165 context()->Plug(v0); | 3183 context()->Plug(v0); |
| 3166 } | 3184 } |
| 3167 | 3185 |
| 3168 | 3186 |
| 3169 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { | 3187 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 3188 ZoneList<Expression*>* args = expr->arguments(); |
| 3170 ASSERT(args->length() >= 2); | 3189 ASSERT(args->length() >= 2); |
| 3171 | 3190 |
| 3172 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 3191 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| 3173 for (int i = 0; i < arg_count + 1; i++) { | 3192 for (int i = 0; i < arg_count + 1; i++) { |
| 3174 VisitForStackValue(args->at(i)); | 3193 VisitForStackValue(args->at(i)); |
| 3175 } | 3194 } |
| 3176 VisitForAccumulatorValue(args->last()); // Function. | 3195 VisitForAccumulatorValue(args->last()); // Function. |
| 3177 | 3196 |
| 3178 // InvokeFunction requires the function in a1. Move it in there. | 3197 // InvokeFunction requires the function in a1. Move it in there. |
| 3179 __ mov(a1, result_register()); | 3198 __ mov(a1, result_register()); |
| 3180 ParameterCount count(arg_count); | 3199 ParameterCount count(arg_count); |
| 3181 __ InvokeFunction(a1, count, CALL_FUNCTION, | 3200 __ InvokeFunction(a1, count, CALL_FUNCTION, |
| 3182 NullCallWrapper(), CALL_AS_METHOD); | 3201 NullCallWrapper(), CALL_AS_METHOD); |
| 3183 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3202 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3184 context()->Plug(v0); | 3203 context()->Plug(v0); |
| 3185 } | 3204 } |
| 3186 | 3205 |
| 3187 | 3206 |
| 3188 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { | 3207 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { |
| 3189 RegExpConstructResultStub stub; | 3208 RegExpConstructResultStub stub; |
| 3209 ZoneList<Expression*>* args = expr->arguments(); |
| 3190 ASSERT(args->length() == 3); | 3210 ASSERT(args->length() == 3); |
| 3191 VisitForStackValue(args->at(0)); | 3211 VisitForStackValue(args->at(0)); |
| 3192 VisitForStackValue(args->at(1)); | 3212 VisitForStackValue(args->at(1)); |
| 3193 VisitForStackValue(args->at(2)); | 3213 VisitForStackValue(args->at(2)); |
| 3194 __ CallStub(&stub); | 3214 __ CallStub(&stub); |
| 3195 context()->Plug(v0); | 3215 context()->Plug(v0); |
| 3196 } | 3216 } |
| 3197 | 3217 |
| 3198 | 3218 |
| 3199 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) { | 3219 void FullCodeGenerator::EmitSwapElements(CallRuntime* expr) { |
| 3220 ZoneList<Expression*>* args = expr->arguments(); |
| 3200 ASSERT(args->length() == 3); | 3221 ASSERT(args->length() == 3); |
| 3201 VisitForStackValue(args->at(0)); | 3222 VisitForStackValue(args->at(0)); |
| 3202 VisitForStackValue(args->at(1)); | 3223 VisitForStackValue(args->at(1)); |
| 3203 VisitForStackValue(args->at(2)); | 3224 VisitForStackValue(args->at(2)); |
| 3204 Label done; | 3225 Label done; |
| 3205 Label slow_case; | 3226 Label slow_case; |
| 3206 Register object = a0; | 3227 Register object = a0; |
| 3207 Register index1 = a1; | 3228 Register index1 = a1; |
| 3208 Register index2 = a2; | 3229 Register index2 = a2; |
| 3209 Register elements = a3; | 3230 Register elements = a3; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3286 __ jmp(&done); | 3307 __ jmp(&done); |
| 3287 | 3308 |
| 3288 __ bind(&slow_case); | 3309 __ bind(&slow_case); |
| 3289 __ CallRuntime(Runtime::kSwapElements, 3); | 3310 __ CallRuntime(Runtime::kSwapElements, 3); |
| 3290 | 3311 |
| 3291 __ bind(&done); | 3312 __ bind(&done); |
| 3292 context()->Plug(v0); | 3313 context()->Plug(v0); |
| 3293 } | 3314 } |
| 3294 | 3315 |
| 3295 | 3316 |
| 3296 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { | 3317 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { |
| 3318 ZoneList<Expression*>* args = expr->arguments(); |
| 3297 ASSERT_EQ(2, args->length()); | 3319 ASSERT_EQ(2, args->length()); |
| 3298 | 3320 |
| 3299 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 3321 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
| 3300 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); | 3322 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
| 3301 | 3323 |
| 3302 Handle<FixedArray> jsfunction_result_caches( | 3324 Handle<FixedArray> jsfunction_result_caches( |
| 3303 isolate()->global_context()->jsfunction_result_caches()); | 3325 isolate()->global_context()->jsfunction_result_caches()); |
| 3304 if (jsfunction_result_caches->length() <= cache_id) { | 3326 if (jsfunction_result_caches->length() <= cache_id) { |
| 3305 __ Abort("Attempt to use undefined cache."); | 3327 __ Abort("Attempt to use undefined cache."); |
| 3306 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 3328 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3339 __ bind(¬_found); | 3361 __ bind(¬_found); |
| 3340 // Call runtime to perform the lookup. | 3362 // Call runtime to perform the lookup. |
| 3341 __ Push(cache, key); | 3363 __ Push(cache, key); |
| 3342 __ CallRuntime(Runtime::kGetFromCache, 2); | 3364 __ CallRuntime(Runtime::kGetFromCache, 2); |
| 3343 | 3365 |
| 3344 __ bind(&done); | 3366 __ bind(&done); |
| 3345 context()->Plug(v0); | 3367 context()->Plug(v0); |
| 3346 } | 3368 } |
| 3347 | 3369 |
| 3348 | 3370 |
| 3349 void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) { | 3371 void FullCodeGenerator::EmitIsRegExpEquivalent(CallRuntime* expr) { |
| 3372 ZoneList<Expression*>* args = expr->arguments(); |
| 3350 ASSERT_EQ(2, args->length()); | 3373 ASSERT_EQ(2, args->length()); |
| 3351 | 3374 |
| 3352 Register right = v0; | 3375 Register right = v0; |
| 3353 Register left = a1; | 3376 Register left = a1; |
| 3354 Register tmp = a2; | 3377 Register tmp = a2; |
| 3355 Register tmp2 = a3; | 3378 Register tmp2 = a3; |
| 3356 | 3379 |
| 3357 VisitForStackValue(args->at(0)); | 3380 VisitForStackValue(args->at(0)); |
| 3358 VisitForAccumulatorValue(args->at(1)); // Result (right) in v0. | 3381 VisitForAccumulatorValue(args->at(1)); // Result (right) in v0. |
| 3359 __ pop(left); | 3382 __ pop(left); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3376 __ LoadRoot(v0, Heap::kFalseValueRootIndex); | 3399 __ LoadRoot(v0, Heap::kFalseValueRootIndex); |
| 3377 __ jmp(&done); | 3400 __ jmp(&done); |
| 3378 __ bind(&ok); | 3401 __ bind(&ok); |
| 3379 __ LoadRoot(v0, Heap::kTrueValueRootIndex); | 3402 __ LoadRoot(v0, Heap::kTrueValueRootIndex); |
| 3380 __ bind(&done); | 3403 __ bind(&done); |
| 3381 | 3404 |
| 3382 context()->Plug(v0); | 3405 context()->Plug(v0); |
| 3383 } | 3406 } |
| 3384 | 3407 |
| 3385 | 3408 |
| 3386 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { | 3409 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
| 3410 ZoneList<Expression*>* args = expr->arguments(); |
| 3387 VisitForAccumulatorValue(args->at(0)); | 3411 VisitForAccumulatorValue(args->at(0)); |
| 3388 | 3412 |
| 3389 Label materialize_true, materialize_false; | 3413 Label materialize_true, materialize_false; |
| 3390 Label* if_true = NULL; | 3414 Label* if_true = NULL; |
| 3391 Label* if_false = NULL; | 3415 Label* if_false = NULL; |
| 3392 Label* fall_through = NULL; | 3416 Label* fall_through = NULL; |
| 3393 context()->PrepareTest(&materialize_true, &materialize_false, | 3417 context()->PrepareTest(&materialize_true, &materialize_false, |
| 3394 &if_true, &if_false, &fall_through); | 3418 &if_true, &if_false, &fall_through); |
| 3395 | 3419 |
| 3396 __ lw(a0, FieldMemOperand(v0, String::kHashFieldOffset)); | 3420 __ lw(a0, FieldMemOperand(v0, String::kHashFieldOffset)); |
| 3397 __ And(a0, a0, Operand(String::kContainsCachedArrayIndexMask)); | 3421 __ And(a0, a0, Operand(String::kContainsCachedArrayIndexMask)); |
| 3398 | 3422 |
| 3399 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 3423 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 3400 Split(eq, a0, Operand(zero_reg), if_true, if_false, fall_through); | 3424 Split(eq, a0, Operand(zero_reg), if_true, if_false, fall_through); |
| 3401 | 3425 |
| 3402 context()->Plug(if_true, if_false); | 3426 context()->Plug(if_true, if_false); |
| 3403 } | 3427 } |
| 3404 | 3428 |
| 3405 | 3429 |
| 3406 void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { | 3430 void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) { |
| 3431 ZoneList<Expression*>* args = expr->arguments(); |
| 3407 ASSERT(args->length() == 1); | 3432 ASSERT(args->length() == 1); |
| 3408 VisitForAccumulatorValue(args->at(0)); | 3433 VisitForAccumulatorValue(args->at(0)); |
| 3409 | 3434 |
| 3410 if (FLAG_debug_code) { | 3435 if (FLAG_debug_code) { |
| 3411 __ AbortIfNotString(v0); | 3436 __ AbortIfNotString(v0); |
| 3412 } | 3437 } |
| 3413 | 3438 |
| 3414 __ lw(v0, FieldMemOperand(v0, String::kHashFieldOffset)); | 3439 __ lw(v0, FieldMemOperand(v0, String::kHashFieldOffset)); |
| 3415 __ IndexFromHash(v0, v0); | 3440 __ IndexFromHash(v0, v0); |
| 3416 | 3441 |
| 3417 context()->Plug(v0); | 3442 context()->Plug(v0); |
| 3418 } | 3443 } |
| 3419 | 3444 |
| 3420 | 3445 |
| 3421 void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) { | 3446 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { |
| 3422 Label bailout, done, one_char_separator, long_separator, | 3447 Label bailout, done, one_char_separator, long_separator, |
| 3423 non_trivial_array, not_size_one_array, loop, | 3448 non_trivial_array, not_size_one_array, loop, |
| 3424 empty_separator_loop, one_char_separator_loop, | 3449 empty_separator_loop, one_char_separator_loop, |
| 3425 one_char_separator_loop_entry, long_separator_loop; | 3450 one_char_separator_loop_entry, long_separator_loop; |
| 3426 | 3451 ZoneList<Expression*>* args = expr->arguments(); |
| 3427 ASSERT(args->length() == 2); | 3452 ASSERT(args->length() == 2); |
| 3428 VisitForStackValue(args->at(1)); | 3453 VisitForStackValue(args->at(1)); |
| 3429 VisitForAccumulatorValue(args->at(0)); | 3454 VisitForAccumulatorValue(args->at(0)); |
| 3430 | 3455 |
| 3431 // All aliases of the same register have disjoint lifetimes. | 3456 // All aliases of the same register have disjoint lifetimes. |
| 3432 Register array = v0; | 3457 Register array = v0; |
| 3433 Register elements = no_reg; // Will be v0. | 3458 Register elements = no_reg; // Will be v0. |
| 3434 Register result = no_reg; // Will be v0. | 3459 Register result = no_reg; // Will be v0. |
| 3435 Register separator = a1; | 3460 Register separator = a1; |
| 3436 Register array_length = a2; | 3461 Register array_length = a2; |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3752 context()->Plug(Heap::kUndefinedValueRootIndex); | 3777 context()->Plug(Heap::kUndefinedValueRootIndex); |
| 3753 break; | 3778 break; |
| 3754 } | 3779 } |
| 3755 | 3780 |
| 3756 case Token::NOT: { | 3781 case Token::NOT: { |
| 3757 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); | 3782 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); |
| 3758 if (context()->IsEffect()) { | 3783 if (context()->IsEffect()) { |
| 3759 // Unary NOT has no side effects so it's only necessary to visit the | 3784 // Unary NOT has no side effects so it's only necessary to visit the |
| 3760 // subexpression. Match the optimizing compiler by not branching. | 3785 // subexpression. Match the optimizing compiler by not branching. |
| 3761 VisitForEffect(expr->expression()); | 3786 VisitForEffect(expr->expression()); |
| 3787 } else if (context()->IsTest()) { |
| 3788 const TestContext* test = TestContext::cast(context()); |
| 3789 // The labels are swapped for the recursive call. |
| 3790 VisitForControl(expr->expression(), |
| 3791 test->false_label(), |
| 3792 test->true_label(), |
| 3793 test->fall_through()); |
| 3794 context()->Plug(test->true_label(), test->false_label()); |
| 3762 } else { | 3795 } else { |
| 3763 Label materialize_true, materialize_false; | 3796 // We handle value contexts explicitly rather than simply visiting |
| 3764 Label* if_true = NULL; | 3797 // for control and plugging the control flow into the context, |
| 3765 Label* if_false = NULL; | 3798 // because we need to prepare a pair of extra administrative AST ids |
| 3766 Label* fall_through = NULL; | 3799 // for the optimizing compiler. |
| 3767 | 3800 ASSERT(context()->IsAccumulatorValue() || context()->IsStackValue()); |
| 3768 // Notice that the labels are swapped. | 3801 Label materialize_true, materialize_false, done; |
| 3769 context()->PrepareTest(&materialize_true, &materialize_false, | 3802 VisitForControl(expr->expression(), |
| 3770 &if_false, &if_true, &fall_through); | 3803 &materialize_false, |
| 3771 if (context()->IsTest()) ForwardBailoutToChild(expr); | 3804 &materialize_true, |
| 3772 VisitForControl(expr->expression(), if_true, if_false, fall_through); | 3805 &materialize_true); |
| 3773 context()->Plug(if_false, if_true); // Labels swapped. | 3806 __ bind(&materialize_true); |
| 3807 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); |
| 3808 __ LoadRoot(v0, Heap::kTrueValueRootIndex); |
| 3809 if (context()->IsStackValue()) __ push(v0); |
| 3810 __ jmp(&done); |
| 3811 __ bind(&materialize_false); |
| 3812 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); |
| 3813 __ LoadRoot(v0, Heap::kFalseValueRootIndex); |
| 3814 if (context()->IsStackValue()) __ push(v0); |
| 3815 __ bind(&done); |
| 3774 } | 3816 } |
| 3775 break; | 3817 break; |
| 3776 } | 3818 } |
| 3777 | 3819 |
| 3778 case Token::TYPEOF: { | 3820 case Token::TYPEOF: { |
| 3779 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 3821 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
| 3780 { StackValueContext context(this); | 3822 { StackValueContext context(this); |
| 3781 VisitForTypeofValue(expr->expression()); | 3823 VisitForTypeofValue(expr->expression()); |
| 3782 } | 3824 } |
| 3783 __ CallRuntime(Runtime::kTypeof, 1); | 3825 __ CallRuntime(Runtime::kTypeof, 1); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4025 __ bind(&slow); | 4067 __ bind(&slow); |
| 4026 __ li(a0, Operand(proxy->name())); | 4068 __ li(a0, Operand(proxy->name())); |
| 4027 __ Push(cp, a0); | 4069 __ Push(cp, a0); |
| 4028 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 4070 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
| 4029 PrepareForBailout(expr, TOS_REG); | 4071 PrepareForBailout(expr, TOS_REG); |
| 4030 __ bind(&done); | 4072 __ bind(&done); |
| 4031 | 4073 |
| 4032 context()->Plug(v0); | 4074 context()->Plug(v0); |
| 4033 } else { | 4075 } else { |
| 4034 // This expression cannot throw a reference error at the top level. | 4076 // This expression cannot throw a reference error at the top level. |
| 4035 VisitInCurrentContext(expr); | 4077 VisitInDuplicateContext(expr); |
| 4036 } | 4078 } |
| 4037 } | 4079 } |
| 4038 | 4080 |
| 4039 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 4081 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
| 4082 Expression* sub_expr, |
| 4040 Handle<String> check) { | 4083 Handle<String> check) { |
| 4041 Label materialize_true, materialize_false; | 4084 Label materialize_true, materialize_false; |
| 4042 Label* if_true = NULL; | 4085 Label* if_true = NULL; |
| 4043 Label* if_false = NULL; | 4086 Label* if_false = NULL; |
| 4044 Label* fall_through = NULL; | 4087 Label* fall_through = NULL; |
| 4045 context()->PrepareTest(&materialize_true, &materialize_false, | 4088 context()->PrepareTest(&materialize_true, &materialize_false, |
| 4046 &if_true, &if_false, &fall_through); | 4089 &if_true, &if_false, &fall_through); |
| 4047 | 4090 |
| 4048 { AccumulatorValueContext context(this); | 4091 { AccumulatorValueContext context(this); |
| 4049 VisitForTypeofValue(expr); | 4092 VisitForTypeofValue(sub_expr); |
| 4050 } | 4093 } |
| 4051 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 4094 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4052 | 4095 |
| 4053 if (check->Equals(isolate()->heap()->number_symbol())) { | 4096 if (check->Equals(isolate()->heap()->number_symbol())) { |
| 4054 __ JumpIfSmi(v0, if_true); | 4097 __ JumpIfSmi(v0, if_true); |
| 4055 __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset)); | 4098 __ lw(v0, FieldMemOperand(v0, HeapObject::kMapOffset)); |
| 4056 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 4099 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
| 4057 Split(eq, v0, Operand(at), if_true, if_false, fall_through); | 4100 Split(eq, v0, Operand(at), if_true, if_false, fall_through); |
| 4058 } else if (check->Equals(isolate()->heap()->string_symbol())) { | 4101 } else if (check->Equals(isolate()->heap()->string_symbol())) { |
| 4059 __ JumpIfSmi(v0, if_false); | 4102 __ JumpIfSmi(v0, if_false); |
| 4060 // Check for undetectable objects => false. | 4103 // Check for undetectable objects => false. |
| 4061 __ GetObjectType(v0, v0, a1); | 4104 __ GetObjectType(v0, v0, a1); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4127 Label* fall_through = NULL; | 4170 Label* fall_through = NULL; |
| 4128 context()->PrepareTest(&materialize_true, &materialize_false, | 4171 context()->PrepareTest(&materialize_true, &materialize_false, |
| 4129 &if_true, &if_false, &fall_through); | 4172 &if_true, &if_false, &fall_through); |
| 4130 | 4173 |
| 4131 Token::Value op = expr->op(); | 4174 Token::Value op = expr->op(); |
| 4132 VisitForStackValue(expr->left()); | 4175 VisitForStackValue(expr->left()); |
| 4133 switch (op) { | 4176 switch (op) { |
| 4134 case Token::IN: | 4177 case Token::IN: |
| 4135 VisitForStackValue(expr->right()); | 4178 VisitForStackValue(expr->right()); |
| 4136 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); | 4179 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
| 4137 PrepareForBailoutBeforeSplit(false, NULL, NULL); | 4180 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
| 4138 __ LoadRoot(t0, Heap::kTrueValueRootIndex); | 4181 __ LoadRoot(t0, Heap::kTrueValueRootIndex); |
| 4139 Split(eq, v0, Operand(t0), if_true, if_false, fall_through); | 4182 Split(eq, v0, Operand(t0), if_true, if_false, fall_through); |
| 4140 break; | 4183 break; |
| 4141 | 4184 |
| 4142 case Token::INSTANCEOF: { | 4185 case Token::INSTANCEOF: { |
| 4143 VisitForStackValue(expr->right()); | 4186 VisitForStackValue(expr->right()); |
| 4144 InstanceofStub stub(InstanceofStub::kNoFlags); | 4187 InstanceofStub stub(InstanceofStub::kNoFlags); |
| 4145 __ CallStub(&stub); | 4188 __ CallStub(&stub); |
| 4146 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 4189 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4147 // The stub returns 0 for true. | 4190 // The stub returns 0 for true. |
| 4148 Split(eq, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4191 Split(eq, v0, Operand(zero_reg), if_true, if_false, fall_through); |
| 4149 break; | 4192 break; |
| 4150 } | 4193 } |
| 4151 | 4194 |
| 4152 default: { | 4195 default: { |
| 4153 VisitForAccumulatorValue(expr->right()); | 4196 VisitForAccumulatorValue(expr->right()); |
| 4154 Condition cc = eq; | 4197 Condition cc = eq; |
| 4155 switch (op) { | 4198 switch (op) { |
| 4156 case Token::EQ_STRICT: | 4199 case Token::EQ_STRICT: |
| (...skipping 27 matching lines...) Expand all Loading... |
| 4184 __ Or(a2, a0, Operand(a1)); | 4227 __ Or(a2, a0, Operand(a1)); |
| 4185 patch_site.EmitJumpIfNotSmi(a2, &slow_case); | 4228 patch_site.EmitJumpIfNotSmi(a2, &slow_case); |
| 4186 Split(cc, a1, Operand(a0), if_true, if_false, NULL); | 4229 Split(cc, a1, Operand(a0), if_true, if_false, NULL); |
| 4187 __ bind(&slow_case); | 4230 __ bind(&slow_case); |
| 4188 } | 4231 } |
| 4189 // Record position and call the compare IC. | 4232 // Record position and call the compare IC. |
| 4190 SetSourcePosition(expr->position()); | 4233 SetSourcePosition(expr->position()); |
| 4191 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4234 Handle<Code> ic = CompareIC::GetUninitialized(op); |
| 4192 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); | 4235 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 4193 patch_site.EmitPatchInfo(); | 4236 patch_site.EmitPatchInfo(); |
| 4194 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 4237 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4195 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); | 4238 Split(cc, v0, Operand(zero_reg), if_true, if_false, fall_through); |
| 4196 } | 4239 } |
| 4197 } | 4240 } |
| 4198 | 4241 |
| 4199 // Convert the result of the comparison into one expected for this | 4242 // Convert the result of the comparison into one expected for this |
| 4200 // expression's context. | 4243 // expression's context. |
| 4201 context()->Plug(if_true, if_false); | 4244 context()->Plug(if_true, if_false); |
| 4202 } | 4245 } |
| 4203 | 4246 |
| 4204 | 4247 |
| 4205 void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, | 4248 void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, |
| 4206 Expression* sub_expr, | 4249 Expression* sub_expr, |
| 4207 NilValue nil) { | 4250 NilValue nil) { |
| 4208 Label materialize_true, materialize_false; | 4251 Label materialize_true, materialize_false; |
| 4209 Label* if_true = NULL; | 4252 Label* if_true = NULL; |
| 4210 Label* if_false = NULL; | 4253 Label* if_false = NULL; |
| 4211 Label* fall_through = NULL; | 4254 Label* fall_through = NULL; |
| 4212 context()->PrepareTest(&materialize_true, &materialize_false, | 4255 context()->PrepareTest(&materialize_true, &materialize_false, |
| 4213 &if_true, &if_false, &fall_through); | 4256 &if_true, &if_false, &fall_through); |
| 4214 | 4257 |
| 4215 VisitForAccumulatorValue(sub_expr); | 4258 VisitForAccumulatorValue(sub_expr); |
| 4216 PrepareForBailoutBeforeSplit(true, if_true, if_false); | 4259 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4217 Heap::RootListIndex nil_value = nil == kNullValue ? | 4260 Heap::RootListIndex nil_value = nil == kNullValue ? |
| 4218 Heap::kNullValueRootIndex : | 4261 Heap::kNullValueRootIndex : |
| 4219 Heap::kUndefinedValueRootIndex; | 4262 Heap::kUndefinedValueRootIndex; |
| 4220 __ mov(a0, result_register()); | 4263 __ mov(a0, result_register()); |
| 4221 __ LoadRoot(a1, nil_value); | 4264 __ LoadRoot(a1, nil_value); |
| 4222 if (expr->op() == Token::EQ_STRICT) { | 4265 if (expr->op() == Token::EQ_STRICT) { |
| 4223 Split(eq, a0, Operand(a1), if_true, if_false, fall_through); | 4266 Split(eq, a0, Operand(a1), if_true, if_false, fall_through); |
| 4224 } else { | 4267 } else { |
| 4225 Heap::RootListIndex other_nil_value = nil == kNullValue ? | 4268 Heap::RootListIndex other_nil_value = nil == kNullValue ? |
| 4226 Heap::kUndefinedValueRootIndex : | 4269 Heap::kUndefinedValueRootIndex : |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4343 *context_length = 0; | 4386 *context_length = 0; |
| 4344 return previous_; | 4387 return previous_; |
| 4345 } | 4388 } |
| 4346 | 4389 |
| 4347 | 4390 |
| 4348 #undef __ | 4391 #undef __ |
| 4349 | 4392 |
| 4350 } } // namespace v8::internal | 4393 } } // namespace v8::internal |
| 4351 | 4394 |
| 4352 #endif // V8_TARGET_ARCH_MIPS | 4395 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |