| 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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 387 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
| 388 codegen()->GetVar(result_register(), var); | 388 codegen()->GetVar(result_register(), var); |
| 389 __ push(result_register()); | 389 __ push(result_register()); |
| 390 } | 390 } |
| 391 | 391 |
| 392 | 392 |
| 393 void FullCodeGenerator::TestContext::Plug(Variable* var) const { | 393 void FullCodeGenerator::TestContext::Plug(Variable* var) const { |
| 394 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); | 394 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); |
| 395 // For simplicity we always test the accumulator register. | 395 // For simplicity we always test the accumulator register. |
| 396 codegen()->GetVar(result_register(), var); | 396 codegen()->GetVar(result_register(), var); |
| 397 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); | 397 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
| 398 codegen()->DoTest(this); | 398 codegen()->DoTest(this); |
| 399 } | 399 } |
| 400 | 400 |
| 401 | 401 |
| 402 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { | 402 void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const { |
| 403 } | 403 } |
| 404 | 404 |
| 405 | 405 |
| 406 void FullCodeGenerator::AccumulatorValueContext::Plug( | 406 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 407 Heap::RootListIndex index) const { | 407 Heap::RootListIndex index) const { |
| 408 __ LoadRoot(result_register(), index); | 408 __ LoadRoot(result_register(), index); |
| 409 } | 409 } |
| 410 | 410 |
| 411 | 411 |
| 412 void FullCodeGenerator::StackValueContext::Plug( | 412 void FullCodeGenerator::StackValueContext::Plug( |
| 413 Heap::RootListIndex index) const { | 413 Heap::RootListIndex index) const { |
| 414 __ LoadRoot(result_register(), index); | 414 __ LoadRoot(result_register(), index); |
| 415 __ push(result_register()); | 415 __ push(result_register()); |
| 416 } | 416 } |
| 417 | 417 |
| 418 | 418 |
| 419 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { | 419 void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const { |
| 420 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, | 420 codegen()->PrepareForBailoutBeforeSplit(condition(), |
| 421 true, | 421 true, |
| 422 true_label_, | 422 true_label_, |
| 423 false_label_); | 423 false_label_); |
| 424 if (index == Heap::kUndefinedValueRootIndex || | 424 if (index == Heap::kUndefinedValueRootIndex || |
| 425 index == Heap::kNullValueRootIndex || | 425 index == Heap::kNullValueRootIndex || |
| 426 index == Heap::kFalseValueRootIndex) { | 426 index == Heap::kFalseValueRootIndex) { |
| 427 if (false_label_ != fall_through_) __ b(false_label_); | 427 if (false_label_ != fall_through_) __ b(false_label_); |
| 428 } else if (index == Heap::kTrueValueRootIndex) { | 428 } else if (index == Heap::kTrueValueRootIndex) { |
| 429 if (true_label_ != fall_through_) __ b(true_label_); | 429 if (true_label_ != fall_through_) __ b(true_label_); |
| 430 } else { | 430 } else { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 445 | 445 |
| 446 | 446 |
| 447 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { | 447 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { |
| 448 // Immediates cannot be pushed directly. | 448 // Immediates cannot be pushed directly. |
| 449 __ mov(result_register(), Operand(lit)); | 449 __ mov(result_register(), Operand(lit)); |
| 450 __ push(result_register()); | 450 __ push(result_register()); |
| 451 } | 451 } |
| 452 | 452 |
| 453 | 453 |
| 454 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { | 454 void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const { |
| 455 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, | 455 codegen()->PrepareForBailoutBeforeSplit(condition(), |
| 456 true, | 456 true, |
| 457 true_label_, | 457 true_label_, |
| 458 false_label_); | 458 false_label_); |
| 459 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals. | 459 ASSERT(!lit->IsUndetectableObject()); // There are no undetectable literals. |
| 460 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { | 460 if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) { |
| 461 if (false_label_ != fall_through_) __ b(false_label_); | 461 if (false_label_ != fall_through_) __ b(false_label_); |
| 462 } else if (lit->IsTrue() || lit->IsJSObject()) { | 462 } else if (lit->IsTrue() || lit->IsJSObject()) { |
| 463 if (true_label_ != fall_through_) __ b(true_label_); | 463 if (true_label_ != fall_through_) __ b(true_label_); |
| 464 } else if (lit->IsString()) { | 464 } else if (lit->IsString()) { |
| 465 if (String::cast(*lit)->length() == 0) { | 465 if (String::cast(*lit)->length() == 0) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 __ str(reg, MemOperand(sp, 0)); | 504 __ str(reg, MemOperand(sp, 0)); |
| 505 } | 505 } |
| 506 | 506 |
| 507 | 507 |
| 508 void FullCodeGenerator::TestContext::DropAndPlug(int count, | 508 void FullCodeGenerator::TestContext::DropAndPlug(int count, |
| 509 Register reg) const { | 509 Register reg) const { |
| 510 ASSERT(count > 0); | 510 ASSERT(count > 0); |
| 511 // For simplicity we always test the accumulator register. | 511 // For simplicity we always test the accumulator register. |
| 512 __ Drop(count); | 512 __ Drop(count); |
| 513 __ Move(result_register(), reg); | 513 __ Move(result_register(), reg); |
| 514 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); | 514 codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL); |
| 515 codegen()->DoTest(this); | 515 codegen()->DoTest(this); |
| 516 } | 516 } |
| 517 | 517 |
| 518 | 518 |
| 519 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, | 519 void FullCodeGenerator::EffectContext::Plug(Label* materialize_true, |
| 520 Label* materialize_false) const { | 520 Label* materialize_false) const { |
| 521 ASSERT(materialize_true == materialize_false); | 521 ASSERT(materialize_true == materialize_false); |
| 522 __ bind(materialize_true); | 522 __ bind(materialize_true); |
| 523 } | 523 } |
| 524 | 524 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 | 571 |
| 572 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { | 572 void FullCodeGenerator::StackValueContext::Plug(bool flag) const { |
| 573 Heap::RootListIndex value_root_index = | 573 Heap::RootListIndex value_root_index = |
| 574 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; | 574 flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex; |
| 575 __ LoadRoot(ip, value_root_index); | 575 __ LoadRoot(ip, value_root_index); |
| 576 __ push(ip); | 576 __ push(ip); |
| 577 } | 577 } |
| 578 | 578 |
| 579 | 579 |
| 580 void FullCodeGenerator::TestContext::Plug(bool flag) const { | 580 void FullCodeGenerator::TestContext::Plug(bool flag) const { |
| 581 codegen()->PrepareForBailoutBeforeSplit(TOS_REG, | 581 codegen()->PrepareForBailoutBeforeSplit(condition(), |
| 582 true, | 582 true, |
| 583 true_label_, | 583 true_label_, |
| 584 false_label_); | 584 false_label_); |
| 585 if (flag) { | 585 if (flag) { |
| 586 if (true_label_ != fall_through_) __ b(true_label_); | 586 if (true_label_ != fall_through_) __ b(true_label_); |
| 587 } else { | 587 } else { |
| 588 if (false_label_ != fall_through_) __ b(false_label_); | 588 if (false_label_ != fall_through_) __ b(false_label_); |
| 589 } | 589 } |
| 590 } | 590 } |
| 591 | 591 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 __ RecordWriteContextSlot(scratch0, | 674 __ RecordWriteContextSlot(scratch0, |
| 675 location.offset(), | 675 location.offset(), |
| 676 src, | 676 src, |
| 677 scratch1, | 677 scratch1, |
| 678 kLRHasBeenSaved, | 678 kLRHasBeenSaved, |
| 679 kDontSaveFPRegs); | 679 kDontSaveFPRegs); |
| 680 } | 680 } |
| 681 } | 681 } |
| 682 | 682 |
| 683 | 683 |
| 684 void FullCodeGenerator::PrepareForBailoutBeforeSplit(State state, | 684 void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr, |
| 685 bool should_normalize, | 685 bool should_normalize, |
| 686 Label* if_true, | 686 Label* if_true, |
| 687 Label* if_false) { | 687 Label* if_false) { |
| 688 // Only prepare for bailouts before splits if we're in a test | 688 // Only prepare for bailouts before splits if we're in a test |
| 689 // context. Otherwise, we let the Visit function deal with the | 689 // context. Otherwise, we let the Visit function deal with the |
| 690 // preparation to avoid preparing with the same AST id twice. | 690 // preparation to avoid preparing with the same AST id twice. |
| 691 if (!context()->IsTest() || !info_->IsOptimizable()) return; | 691 if (!context()->IsTest() || !info_->IsOptimizable()) return; |
| 692 | 692 |
| 693 Label skip; | 693 Label skip; |
| 694 if (should_normalize) __ b(&skip); | 694 if (should_normalize) __ b(&skip); |
| 695 | 695 PrepareForBailout(expr, TOS_REG); |
| 696 ForwardBailoutStack* current = forward_bailout_stack_; | |
| 697 while (current != NULL) { | |
| 698 PrepareForBailout(current->expr(), state); | |
| 699 current = current->parent(); | |
| 700 } | |
| 701 | |
| 702 if (should_normalize) { | 696 if (should_normalize) { |
| 703 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 697 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 704 __ cmp(r0, ip); | 698 __ cmp(r0, ip); |
| 705 Split(eq, if_true, if_false, NULL); | 699 Split(eq, if_true, if_false, NULL); |
| 706 __ bind(&skip); | 700 __ bind(&skip); |
| 707 } | 701 } |
| 708 } | 702 } |
| 709 | 703 |
| 710 | 704 |
| 711 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, | 705 void FullCodeGenerator::EmitDeclaration(VariableProxy* proxy, |
| (...skipping 1658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 __ mov(r0, Operand(arg_count)); | 2364 __ mov(r0, Operand(arg_count)); |
| 2371 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | 2365 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); |
| 2372 | 2366 |
| 2373 Handle<Code> construct_builtin = | 2367 Handle<Code> construct_builtin = |
| 2374 isolate()->builtins()->JSConstructCall(); | 2368 isolate()->builtins()->JSConstructCall(); |
| 2375 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 2369 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
| 2376 context()->Plug(r0); | 2370 context()->Plug(r0); |
| 2377 } | 2371 } |
| 2378 | 2372 |
| 2379 | 2373 |
| 2380 void FullCodeGenerator::EmitIsSmi(ZoneList<Expression*>* args) { | 2374 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 2375 ZoneList<Expression*>* args = expr->arguments(); |
| 2381 ASSERT(args->length() == 1); | 2376 ASSERT(args->length() == 1); |
| 2382 | 2377 |
| 2383 VisitForAccumulatorValue(args->at(0)); | 2378 VisitForAccumulatorValue(args->at(0)); |
| 2384 | 2379 |
| 2385 Label materialize_true, materialize_false; | 2380 Label materialize_true, materialize_false; |
| 2386 Label* if_true = NULL; | 2381 Label* if_true = NULL; |
| 2387 Label* if_false = NULL; | 2382 Label* if_false = NULL; |
| 2388 Label* fall_through = NULL; | 2383 Label* fall_through = NULL; |
| 2389 context()->PrepareTest(&materialize_true, &materialize_false, | 2384 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2390 &if_true, &if_false, &fall_through); | 2385 &if_true, &if_false, &fall_through); |
| 2391 | 2386 |
| 2392 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2387 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2393 __ tst(r0, Operand(kSmiTagMask)); | 2388 __ tst(r0, Operand(kSmiTagMask)); |
| 2394 Split(eq, if_true, if_false, fall_through); | 2389 Split(eq, if_true, if_false, fall_through); |
| 2395 | 2390 |
| 2396 context()->Plug(if_true, if_false); | 2391 context()->Plug(if_true, if_false); |
| 2397 } | 2392 } |
| 2398 | 2393 |
| 2399 | 2394 |
| 2400 void FullCodeGenerator::EmitIsNonNegativeSmi(ZoneList<Expression*>* args) { | 2395 void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) { |
| 2396 ZoneList<Expression*>* args = expr->arguments(); |
| 2401 ASSERT(args->length() == 1); | 2397 ASSERT(args->length() == 1); |
| 2402 | 2398 |
| 2403 VisitForAccumulatorValue(args->at(0)); | 2399 VisitForAccumulatorValue(args->at(0)); |
| 2404 | 2400 |
| 2405 Label materialize_true, materialize_false; | 2401 Label materialize_true, materialize_false; |
| 2406 Label* if_true = NULL; | 2402 Label* if_true = NULL; |
| 2407 Label* if_false = NULL; | 2403 Label* if_false = NULL; |
| 2408 Label* fall_through = NULL; | 2404 Label* fall_through = NULL; |
| 2409 context()->PrepareTest(&materialize_true, &materialize_false, | 2405 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2410 &if_true, &if_false, &fall_through); | 2406 &if_true, &if_false, &fall_through); |
| 2411 | 2407 |
| 2412 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2408 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2413 __ tst(r0, Operand(kSmiTagMask | 0x80000000)); | 2409 __ tst(r0, Operand(kSmiTagMask | 0x80000000)); |
| 2414 Split(eq, if_true, if_false, fall_through); | 2410 Split(eq, if_true, if_false, fall_through); |
| 2415 | 2411 |
| 2416 context()->Plug(if_true, if_false); | 2412 context()->Plug(if_true, if_false); |
| 2417 } | 2413 } |
| 2418 | 2414 |
| 2419 | 2415 |
| 2420 void FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) { | 2416 void FullCodeGenerator::EmitIsObject(CallRuntime* expr) { |
| 2417 ZoneList<Expression*>* args = expr->arguments(); |
| 2421 ASSERT(args->length() == 1); | 2418 ASSERT(args->length() == 1); |
| 2422 | 2419 |
| 2423 VisitForAccumulatorValue(args->at(0)); | 2420 VisitForAccumulatorValue(args->at(0)); |
| 2424 | 2421 |
| 2425 Label materialize_true, materialize_false; | 2422 Label materialize_true, materialize_false; |
| 2426 Label* if_true = NULL; | 2423 Label* if_true = NULL; |
| 2427 Label* if_false = NULL; | 2424 Label* if_false = NULL; |
| 2428 Label* fall_through = NULL; | 2425 Label* fall_through = NULL; |
| 2429 context()->PrepareTest(&materialize_true, &materialize_false, | 2426 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2430 &if_true, &if_false, &fall_through); | 2427 &if_true, &if_false, &fall_through); |
| 2431 | 2428 |
| 2432 __ JumpIfSmi(r0, if_false); | 2429 __ JumpIfSmi(r0, if_false); |
| 2433 __ LoadRoot(ip, Heap::kNullValueRootIndex); | 2430 __ LoadRoot(ip, Heap::kNullValueRootIndex); |
| 2434 __ cmp(r0, ip); | 2431 __ cmp(r0, ip); |
| 2435 __ b(eq, if_true); | 2432 __ b(eq, if_true); |
| 2436 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); | 2433 __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 2437 // Undetectable objects behave like undefined when tested with typeof. | 2434 // Undetectable objects behave like undefined when tested with typeof. |
| 2438 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset)); | 2435 __ ldrb(r1, FieldMemOperand(r2, Map::kBitFieldOffset)); |
| 2439 __ tst(r1, Operand(1 << Map::kIsUndetectable)); | 2436 __ tst(r1, Operand(1 << Map::kIsUndetectable)); |
| 2440 __ b(ne, if_false); | 2437 __ b(ne, if_false); |
| 2441 __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | 2438 __ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset)); |
| 2442 __ cmp(r1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2439 __ cmp(r1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 2443 __ b(lt, if_false); | 2440 __ b(lt, if_false); |
| 2444 __ cmp(r1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 2441 __ cmp(r1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 2445 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2442 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2446 Split(le, if_true, if_false, fall_through); | 2443 Split(le, if_true, if_false, fall_through); |
| 2447 | 2444 |
| 2448 context()->Plug(if_true, if_false); | 2445 context()->Plug(if_true, if_false); |
| 2449 } | 2446 } |
| 2450 | 2447 |
| 2451 | 2448 |
| 2452 void FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) { | 2449 void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) { |
| 2450 ZoneList<Expression*>* args = expr->arguments(); |
| 2453 ASSERT(args->length() == 1); | 2451 ASSERT(args->length() == 1); |
| 2454 | 2452 |
| 2455 VisitForAccumulatorValue(args->at(0)); | 2453 VisitForAccumulatorValue(args->at(0)); |
| 2456 | 2454 |
| 2457 Label materialize_true, materialize_false; | 2455 Label materialize_true, materialize_false; |
| 2458 Label* if_true = NULL; | 2456 Label* if_true = NULL; |
| 2459 Label* if_false = NULL; | 2457 Label* if_false = NULL; |
| 2460 Label* fall_through = NULL; | 2458 Label* fall_through = NULL; |
| 2461 context()->PrepareTest(&materialize_true, &materialize_false, | 2459 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2462 &if_true, &if_false, &fall_through); | 2460 &if_true, &if_false, &fall_through); |
| 2463 | 2461 |
| 2464 __ JumpIfSmi(r0, if_false); | 2462 __ JumpIfSmi(r0, if_false); |
| 2465 __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE); | 2463 __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE); |
| 2466 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2464 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2467 Split(ge, if_true, if_false, fall_through); | 2465 Split(ge, if_true, if_false, fall_through); |
| 2468 | 2466 |
| 2469 context()->Plug(if_true, if_false); | 2467 context()->Plug(if_true, if_false); |
| 2470 } | 2468 } |
| 2471 | 2469 |
| 2472 | 2470 |
| 2473 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { | 2471 void FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) { |
| 2472 ZoneList<Expression*>* args = expr->arguments(); |
| 2474 ASSERT(args->length() == 1); | 2473 ASSERT(args->length() == 1); |
| 2475 | 2474 |
| 2476 VisitForAccumulatorValue(args->at(0)); | 2475 VisitForAccumulatorValue(args->at(0)); |
| 2477 | 2476 |
| 2478 Label materialize_true, materialize_false; | 2477 Label materialize_true, materialize_false; |
| 2479 Label* if_true = NULL; | 2478 Label* if_true = NULL; |
| 2480 Label* if_false = NULL; | 2479 Label* if_false = NULL; |
| 2481 Label* fall_through = NULL; | 2480 Label* fall_through = NULL; |
| 2482 context()->PrepareTest(&materialize_true, &materialize_false, | 2481 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2483 &if_true, &if_false, &fall_through); | 2482 &if_true, &if_false, &fall_through); |
| 2484 | 2483 |
| 2485 __ JumpIfSmi(r0, if_false); | 2484 __ JumpIfSmi(r0, if_false); |
| 2486 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); | 2485 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 2487 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset)); | 2486 __ ldrb(r1, FieldMemOperand(r1, Map::kBitFieldOffset)); |
| 2488 __ tst(r1, Operand(1 << Map::kIsUndetectable)); | 2487 __ tst(r1, Operand(1 << Map::kIsUndetectable)); |
| 2489 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2488 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2490 Split(ne, if_true, if_false, fall_through); | 2489 Split(ne, if_true, if_false, fall_through); |
| 2491 | 2490 |
| 2492 context()->Plug(if_true, if_false); | 2491 context()->Plug(if_true, if_false); |
| 2493 } | 2492 } |
| 2494 | 2493 |
| 2495 | 2494 |
| 2496 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( | 2495 void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf( |
| 2497 ZoneList<Expression*>* args) { | 2496 CallRuntime* expr) { |
| 2498 | 2497 ZoneList<Expression*>* args = expr->arguments(); |
| 2499 ASSERT(args->length() == 1); | 2498 ASSERT(args->length() == 1); |
| 2500 | 2499 |
| 2501 VisitForAccumulatorValue(args->at(0)); | 2500 VisitForAccumulatorValue(args->at(0)); |
| 2502 | 2501 |
| 2503 Label materialize_true, materialize_false; | 2502 Label materialize_true, materialize_false; |
| 2504 Label* if_true = NULL; | 2503 Label* if_true = NULL; |
| 2505 Label* if_false = NULL; | 2504 Label* if_false = NULL; |
| 2506 Label* fall_through = NULL; | 2505 Label* fall_through = NULL; |
| 2507 context()->PrepareTest(&materialize_true, &materialize_false, | 2506 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2508 &if_true, &if_false, &fall_through); | 2507 &if_true, &if_false, &fall_through); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2567 __ cmp(r2, r3); | 2566 __ cmp(r2, r3); |
| 2568 __ b(ne, if_false); | 2567 __ b(ne, if_false); |
| 2569 | 2568 |
| 2570 // Set the bit in the map to indicate that it has been checked safe for | 2569 // Set the bit in the map to indicate that it has been checked safe for |
| 2571 // default valueOf and set true result. | 2570 // default valueOf and set true result. |
| 2572 __ ldrb(r2, FieldMemOperand(r1, Map::kBitField2Offset)); | 2571 __ ldrb(r2, FieldMemOperand(r1, Map::kBitField2Offset)); |
| 2573 __ orr(r2, r2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); | 2572 __ orr(r2, r2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf)); |
| 2574 __ strb(r2, FieldMemOperand(r1, Map::kBitField2Offset)); | 2573 __ strb(r2, FieldMemOperand(r1, Map::kBitField2Offset)); |
| 2575 __ jmp(if_true); | 2574 __ jmp(if_true); |
| 2576 | 2575 |
| 2577 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2576 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2578 context()->Plug(if_true, if_false); | 2577 context()->Plug(if_true, if_false); |
| 2579 } | 2578 } |
| 2580 | 2579 |
| 2581 | 2580 |
| 2582 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { | 2581 void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) { |
| 2582 ZoneList<Expression*>* args = expr->arguments(); |
| 2583 ASSERT(args->length() == 1); | 2583 ASSERT(args->length() == 1); |
| 2584 | 2584 |
| 2585 VisitForAccumulatorValue(args->at(0)); | 2585 VisitForAccumulatorValue(args->at(0)); |
| 2586 | 2586 |
| 2587 Label materialize_true, materialize_false; | 2587 Label materialize_true, materialize_false; |
| 2588 Label* if_true = NULL; | 2588 Label* if_true = NULL; |
| 2589 Label* if_false = NULL; | 2589 Label* if_false = NULL; |
| 2590 Label* fall_through = NULL; | 2590 Label* fall_through = NULL; |
| 2591 context()->PrepareTest(&materialize_true, &materialize_false, | 2591 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2592 &if_true, &if_false, &fall_through); | 2592 &if_true, &if_false, &fall_through); |
| 2593 | 2593 |
| 2594 __ JumpIfSmi(r0, if_false); | 2594 __ JumpIfSmi(r0, if_false); |
| 2595 __ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE); | 2595 __ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE); |
| 2596 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2596 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2597 Split(eq, if_true, if_false, fall_through); | 2597 Split(eq, if_true, if_false, fall_through); |
| 2598 | 2598 |
| 2599 context()->Plug(if_true, if_false); | 2599 context()->Plug(if_true, if_false); |
| 2600 } | 2600 } |
| 2601 | 2601 |
| 2602 | 2602 |
| 2603 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { | 2603 void FullCodeGenerator::EmitIsArray(CallRuntime* expr) { |
| 2604 ZoneList<Expression*>* args = expr->arguments(); |
| 2604 ASSERT(args->length() == 1); | 2605 ASSERT(args->length() == 1); |
| 2605 | 2606 |
| 2606 VisitForAccumulatorValue(args->at(0)); | 2607 VisitForAccumulatorValue(args->at(0)); |
| 2607 | 2608 |
| 2608 Label materialize_true, materialize_false; | 2609 Label materialize_true, materialize_false; |
| 2609 Label* if_true = NULL; | 2610 Label* if_true = NULL; |
| 2610 Label* if_false = NULL; | 2611 Label* if_false = NULL; |
| 2611 Label* fall_through = NULL; | 2612 Label* fall_through = NULL; |
| 2612 context()->PrepareTest(&materialize_true, &materialize_false, | 2613 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2613 &if_true, &if_false, &fall_through); | 2614 &if_true, &if_false, &fall_through); |
| 2614 | 2615 |
| 2615 __ JumpIfSmi(r0, if_false); | 2616 __ JumpIfSmi(r0, if_false); |
| 2616 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); | 2617 __ CompareObjectType(r0, r1, r1, JS_ARRAY_TYPE); |
| 2617 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2618 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2618 Split(eq, if_true, if_false, fall_through); | 2619 Split(eq, if_true, if_false, fall_through); |
| 2619 | 2620 |
| 2620 context()->Plug(if_true, if_false); | 2621 context()->Plug(if_true, if_false); |
| 2621 } | 2622 } |
| 2622 | 2623 |
| 2623 | 2624 |
| 2624 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { | 2625 void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) { |
| 2626 ZoneList<Expression*>* args = expr->arguments(); |
| 2625 ASSERT(args->length() == 1); | 2627 ASSERT(args->length() == 1); |
| 2626 | 2628 |
| 2627 VisitForAccumulatorValue(args->at(0)); | 2629 VisitForAccumulatorValue(args->at(0)); |
| 2628 | 2630 |
| 2629 Label materialize_true, materialize_false; | 2631 Label materialize_true, materialize_false; |
| 2630 Label* if_true = NULL; | 2632 Label* if_true = NULL; |
| 2631 Label* if_false = NULL; | 2633 Label* if_false = NULL; |
| 2632 Label* fall_through = NULL; | 2634 Label* fall_through = NULL; |
| 2633 context()->PrepareTest(&materialize_true, &materialize_false, | 2635 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2634 &if_true, &if_false, &fall_through); | 2636 &if_true, &if_false, &fall_through); |
| 2635 | 2637 |
| 2636 __ JumpIfSmi(r0, if_false); | 2638 __ JumpIfSmi(r0, if_false); |
| 2637 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); | 2639 __ CompareObjectType(r0, r1, r1, JS_REGEXP_TYPE); |
| 2638 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2640 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2639 Split(eq, if_true, if_false, fall_through); | 2641 Split(eq, if_true, if_false, fall_through); |
| 2640 | 2642 |
| 2641 context()->Plug(if_true, if_false); | 2643 context()->Plug(if_true, if_false); |
| 2642 } | 2644 } |
| 2643 | 2645 |
| 2644 | 2646 |
| 2645 | 2647 |
| 2646 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { | 2648 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) { |
| 2647 ASSERT(args->length() == 0); | 2649 ASSERT(expr->arguments()->length() == 0); |
| 2648 | 2650 |
| 2649 Label materialize_true, materialize_false; | 2651 Label materialize_true, materialize_false; |
| 2650 Label* if_true = NULL; | 2652 Label* if_true = NULL; |
| 2651 Label* if_false = NULL; | 2653 Label* if_false = NULL; |
| 2652 Label* fall_through = NULL; | 2654 Label* fall_through = NULL; |
| 2653 context()->PrepareTest(&materialize_true, &materialize_false, | 2655 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2654 &if_true, &if_false, &fall_through); | 2656 &if_true, &if_false, &fall_through); |
| 2655 | 2657 |
| 2656 // Get the frame pointer for the calling frame. | 2658 // Get the frame pointer for the calling frame. |
| 2657 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 2659 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 2658 | 2660 |
| 2659 // Skip the arguments adaptor frame if it exists. | 2661 // Skip the arguments adaptor frame if it exists. |
| 2660 Label check_frame_marker; | 2662 Label check_frame_marker; |
| 2661 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset)); | 2663 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
| 2662 __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 2664 __ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 2663 __ b(ne, &check_frame_marker); | 2665 __ b(ne, &check_frame_marker); |
| 2664 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset)); | 2666 __ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset)); |
| 2665 | 2667 |
| 2666 // Check the marker in the calling frame. | 2668 // Check the marker in the calling frame. |
| 2667 __ bind(&check_frame_marker); | 2669 __ bind(&check_frame_marker); |
| 2668 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset)); | 2670 __ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset)); |
| 2669 __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); | 2671 __ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); |
| 2670 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2672 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2671 Split(eq, if_true, if_false, fall_through); | 2673 Split(eq, if_true, if_false, fall_through); |
| 2672 | 2674 |
| 2673 context()->Plug(if_true, if_false); | 2675 context()->Plug(if_true, if_false); |
| 2674 } | 2676 } |
| 2675 | 2677 |
| 2676 | 2678 |
| 2677 void FullCodeGenerator::EmitObjectEquals(ZoneList<Expression*>* args) { | 2679 void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) { |
| 2680 ZoneList<Expression*>* args = expr->arguments(); |
| 2678 ASSERT(args->length() == 2); | 2681 ASSERT(args->length() == 2); |
| 2679 | 2682 |
| 2680 // Load the two objects into registers and perform the comparison. | 2683 // Load the two objects into registers and perform the comparison. |
| 2681 VisitForStackValue(args->at(0)); | 2684 VisitForStackValue(args->at(0)); |
| 2682 VisitForAccumulatorValue(args->at(1)); | 2685 VisitForAccumulatorValue(args->at(1)); |
| 2683 | 2686 |
| 2684 Label materialize_true, materialize_false; | 2687 Label materialize_true, materialize_false; |
| 2685 Label* if_true = NULL; | 2688 Label* if_true = NULL; |
| 2686 Label* if_false = NULL; | 2689 Label* if_false = NULL; |
| 2687 Label* fall_through = NULL; | 2690 Label* fall_through = NULL; |
| 2688 context()->PrepareTest(&materialize_true, &materialize_false, | 2691 context()->PrepareTest(&materialize_true, &materialize_false, |
| 2689 &if_true, &if_false, &fall_through); | 2692 &if_true, &if_false, &fall_through); |
| 2690 | 2693 |
| 2691 __ pop(r1); | 2694 __ pop(r1); |
| 2692 __ cmp(r0, r1); | 2695 __ cmp(r0, r1); |
| 2693 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 2696 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 2694 Split(eq, if_true, if_false, fall_through); | 2697 Split(eq, if_true, if_false, fall_through); |
| 2695 | 2698 |
| 2696 context()->Plug(if_true, if_false); | 2699 context()->Plug(if_true, if_false); |
| 2697 } | 2700 } |
| 2698 | 2701 |
| 2699 | 2702 |
| 2700 void FullCodeGenerator::EmitArguments(ZoneList<Expression*>* args) { | 2703 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { |
| 2704 ZoneList<Expression*>* args = expr->arguments(); |
| 2701 ASSERT(args->length() == 1); | 2705 ASSERT(args->length() == 1); |
| 2702 | 2706 |
| 2703 // ArgumentsAccessStub expects the key in edx and the formal | 2707 // ArgumentsAccessStub expects the key in edx and the formal |
| 2704 // parameter count in r0. | 2708 // parameter count in r0. |
| 2705 VisitForAccumulatorValue(args->at(0)); | 2709 VisitForAccumulatorValue(args->at(0)); |
| 2706 __ mov(r1, r0); | 2710 __ mov(r1, r0); |
| 2707 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); | 2711 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); |
| 2708 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | 2712 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); |
| 2709 __ CallStub(&stub); | 2713 __ CallStub(&stub); |
| 2710 context()->Plug(r0); | 2714 context()->Plug(r0); |
| 2711 } | 2715 } |
| 2712 | 2716 |
| 2713 | 2717 |
| 2714 void FullCodeGenerator::EmitArgumentsLength(ZoneList<Expression*>* args) { | 2718 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { |
| 2715 ASSERT(args->length() == 0); | 2719 ASSERT(expr->arguments()->length() == 0); |
| 2716 | |
| 2717 Label exit; | 2720 Label exit; |
| 2718 // Get the number of formal parameters. | 2721 // Get the number of formal parameters. |
| 2719 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); | 2722 __ mov(r0, Operand(Smi::FromInt(info_->scope()->num_parameters()))); |
| 2720 | 2723 |
| 2721 // Check if the calling frame is an arguments adaptor frame. | 2724 // Check if the calling frame is an arguments adaptor frame. |
| 2722 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 2725 __ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 2723 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); | 2726 __ ldr(r3, MemOperand(r2, StandardFrameConstants::kContextOffset)); |
| 2724 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 2727 __ cmp(r3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 2725 __ b(ne, &exit); | 2728 __ b(ne, &exit); |
| 2726 | 2729 |
| 2727 // Arguments adaptor case: Read the arguments length from the | 2730 // Arguments adaptor case: Read the arguments length from the |
| 2728 // adaptor frame. | 2731 // adaptor frame. |
| 2729 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2732 __ ldr(r0, MemOperand(r2, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| 2730 | 2733 |
| 2731 __ bind(&exit); | 2734 __ bind(&exit); |
| 2732 context()->Plug(r0); | 2735 context()->Plug(r0); |
| 2733 } | 2736 } |
| 2734 | 2737 |
| 2735 | 2738 |
| 2736 void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) { | 2739 void FullCodeGenerator::EmitClassOf(CallRuntime* expr) { |
| 2740 ZoneList<Expression*>* args = expr->arguments(); |
| 2737 ASSERT(args->length() == 1); | 2741 ASSERT(args->length() == 1); |
| 2738 Label done, null, function, non_function_constructor; | 2742 Label done, null, function, non_function_constructor; |
| 2739 | 2743 |
| 2740 VisitForAccumulatorValue(args->at(0)); | 2744 VisitForAccumulatorValue(args->at(0)); |
| 2741 | 2745 |
| 2742 // If the object is a smi, we return null. | 2746 // If the object is a smi, we return null. |
| 2743 __ JumpIfSmi(r0, &null); | 2747 __ JumpIfSmi(r0, &null); |
| 2744 | 2748 |
| 2745 // Check that the object is a JS object but take special care of JS | 2749 // Check that the object is a JS object but take special care of JS |
| 2746 // functions to make sure they have 'Function' as their class. | 2750 // functions to make sure they have 'Function' as their class. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2786 __ bind(&null); | 2790 __ bind(&null); |
| 2787 __ LoadRoot(r0, Heap::kNullValueRootIndex); | 2791 __ LoadRoot(r0, Heap::kNullValueRootIndex); |
| 2788 | 2792 |
| 2789 // All done. | 2793 // All done. |
| 2790 __ bind(&done); | 2794 __ bind(&done); |
| 2791 | 2795 |
| 2792 context()->Plug(r0); | 2796 context()->Plug(r0); |
| 2793 } | 2797 } |
| 2794 | 2798 |
| 2795 | 2799 |
| 2796 void FullCodeGenerator::EmitLog(ZoneList<Expression*>* args) { | 2800 void FullCodeGenerator::EmitLog(CallRuntime* expr) { |
| 2797 // Conditionally generate a log call. | 2801 // Conditionally generate a log call. |
| 2798 // Args: | 2802 // Args: |
| 2799 // 0 (literal string): The type of logging (corresponds to the flags). | 2803 // 0 (literal string): The type of logging (corresponds to the flags). |
| 2800 // This is used to determine whether or not to generate the log call. | 2804 // This is used to determine whether or not to generate the log call. |
| 2801 // 1 (string): Format string. Access the string at argument index 2 | 2805 // 1 (string): Format string. Access the string at argument index 2 |
| 2802 // with '%2s' (see Logger::LogRuntime for all the formats). | 2806 // with '%2s' (see Logger::LogRuntime for all the formats). |
| 2803 // 2 (array): Arguments to the format string. | 2807 // 2 (array): Arguments to the format string. |
| 2808 ZoneList<Expression*>* args = expr->arguments(); |
| 2804 ASSERT_EQ(args->length(), 3); | 2809 ASSERT_EQ(args->length(), 3); |
| 2805 if (CodeGenerator::ShouldGenerateLog(args->at(0))) { | 2810 if (CodeGenerator::ShouldGenerateLog(args->at(0))) { |
| 2806 VisitForStackValue(args->at(1)); | 2811 VisitForStackValue(args->at(1)); |
| 2807 VisitForStackValue(args->at(2)); | 2812 VisitForStackValue(args->at(2)); |
| 2808 __ CallRuntime(Runtime::kLog, 2); | 2813 __ CallRuntime(Runtime::kLog, 2); |
| 2809 } | 2814 } |
| 2810 | 2815 |
| 2811 // Finally, we're expected to leave a value on the top of the stack. | 2816 // Finally, we're expected to leave a value on the top of the stack. |
| 2812 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 2817 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 2813 context()->Plug(r0); | 2818 context()->Plug(r0); |
| 2814 } | 2819 } |
| 2815 | 2820 |
| 2816 | 2821 |
| 2817 void FullCodeGenerator::EmitRandomHeapNumber(ZoneList<Expression*>* args) { | 2822 void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) { |
| 2818 ASSERT(args->length() == 0); | 2823 ASSERT(expr->arguments()->length() == 0); |
| 2819 | |
| 2820 Label slow_allocate_heapnumber; | 2824 Label slow_allocate_heapnumber; |
| 2821 Label heapnumber_allocated; | 2825 Label heapnumber_allocated; |
| 2822 | 2826 |
| 2823 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); | 2827 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); |
| 2824 __ AllocateHeapNumber(r4, r1, r2, r6, &slow_allocate_heapnumber); | 2828 __ AllocateHeapNumber(r4, r1, r2, r6, &slow_allocate_heapnumber); |
| 2825 __ jmp(&heapnumber_allocated); | 2829 __ jmp(&heapnumber_allocated); |
| 2826 | 2830 |
| 2827 __ bind(&slow_allocate_heapnumber); | 2831 __ bind(&slow_allocate_heapnumber); |
| 2828 // Allocate a heap number. | 2832 // Allocate a heap number. |
| 2829 __ CallRuntime(Runtime::kNumberAlloc, 0); | 2833 __ CallRuntime(Runtime::kNumberAlloc, 0); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2861 __ mov(r0, Operand(r4)); | 2865 __ mov(r0, Operand(r4)); |
| 2862 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset)); | 2866 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset)); |
| 2863 __ CallCFunction( | 2867 __ CallCFunction( |
| 2864 ExternalReference::fill_heap_number_with_random_function(isolate()), 2); | 2868 ExternalReference::fill_heap_number_with_random_function(isolate()), 2); |
| 2865 } | 2869 } |
| 2866 | 2870 |
| 2867 context()->Plug(r0); | 2871 context()->Plug(r0); |
| 2868 } | 2872 } |
| 2869 | 2873 |
| 2870 | 2874 |
| 2871 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) { | 2875 void FullCodeGenerator::EmitSubString(CallRuntime* expr) { |
| 2872 // Load the arguments on the stack and call the stub. | 2876 // Load the arguments on the stack and call the stub. |
| 2873 SubStringStub stub; | 2877 SubStringStub stub; |
| 2878 ZoneList<Expression*>* args = expr->arguments(); |
| 2874 ASSERT(args->length() == 3); | 2879 ASSERT(args->length() == 3); |
| 2875 VisitForStackValue(args->at(0)); | 2880 VisitForStackValue(args->at(0)); |
| 2876 VisitForStackValue(args->at(1)); | 2881 VisitForStackValue(args->at(1)); |
| 2877 VisitForStackValue(args->at(2)); | 2882 VisitForStackValue(args->at(2)); |
| 2878 __ CallStub(&stub); | 2883 __ CallStub(&stub); |
| 2879 context()->Plug(r0); | 2884 context()->Plug(r0); |
| 2880 } | 2885 } |
| 2881 | 2886 |
| 2882 | 2887 |
| 2883 void FullCodeGenerator::EmitRegExpExec(ZoneList<Expression*>* args) { | 2888 void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) { |
| 2884 // Load the arguments on the stack and call the stub. | 2889 // Load the arguments on the stack and call the stub. |
| 2885 RegExpExecStub stub; | 2890 RegExpExecStub stub; |
| 2891 ZoneList<Expression*>* args = expr->arguments(); |
| 2886 ASSERT(args->length() == 4); | 2892 ASSERT(args->length() == 4); |
| 2887 VisitForStackValue(args->at(0)); | 2893 VisitForStackValue(args->at(0)); |
| 2888 VisitForStackValue(args->at(1)); | 2894 VisitForStackValue(args->at(1)); |
| 2889 VisitForStackValue(args->at(2)); | 2895 VisitForStackValue(args->at(2)); |
| 2890 VisitForStackValue(args->at(3)); | 2896 VisitForStackValue(args->at(3)); |
| 2891 __ CallStub(&stub); | 2897 __ CallStub(&stub); |
| 2892 context()->Plug(r0); | 2898 context()->Plug(r0); |
| 2893 } | 2899 } |
| 2894 | 2900 |
| 2895 | 2901 |
| 2896 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { | 2902 void FullCodeGenerator::EmitValueOf(CallRuntime* expr) { |
| 2903 ZoneList<Expression*>* args = expr->arguments(); |
| 2897 ASSERT(args->length() == 1); | 2904 ASSERT(args->length() == 1); |
| 2898 | |
| 2899 VisitForAccumulatorValue(args->at(0)); // Load the object. | 2905 VisitForAccumulatorValue(args->at(0)); // Load the object. |
| 2900 | 2906 |
| 2901 Label done; | 2907 Label done; |
| 2902 // If the object is a smi return the object. | 2908 // If the object is a smi return the object. |
| 2903 __ JumpIfSmi(r0, &done); | 2909 __ JumpIfSmi(r0, &done); |
| 2904 // If the object is not a value type, return the object. | 2910 // If the object is not a value type, return the object. |
| 2905 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); | 2911 __ CompareObjectType(r0, r1, r1, JS_VALUE_TYPE); |
| 2906 __ b(ne, &done); | 2912 __ b(ne, &done); |
| 2907 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset)); | 2913 __ ldr(r0, FieldMemOperand(r0, JSValue::kValueOffset)); |
| 2908 | 2914 |
| 2909 __ bind(&done); | 2915 __ bind(&done); |
| 2910 context()->Plug(r0); | 2916 context()->Plug(r0); |
| 2911 } | 2917 } |
| 2912 | 2918 |
| 2913 | 2919 |
| 2914 void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) { | 2920 void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { |
| 2915 // Load the arguments on the stack and call the runtime function. | 2921 // Load the arguments on the stack and call the runtime function. |
| 2922 ZoneList<Expression*>* args = expr->arguments(); |
| 2916 ASSERT(args->length() == 2); | 2923 ASSERT(args->length() == 2); |
| 2917 VisitForStackValue(args->at(0)); | 2924 VisitForStackValue(args->at(0)); |
| 2918 VisitForStackValue(args->at(1)); | 2925 VisitForStackValue(args->at(1)); |
| 2919 MathPowStub stub; | 2926 MathPowStub stub; |
| 2920 __ CallStub(&stub); | 2927 __ CallStub(&stub); |
| 2921 context()->Plug(r0); | 2928 context()->Plug(r0); |
| 2922 } | 2929 } |
| 2923 | 2930 |
| 2924 | 2931 |
| 2925 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { | 2932 void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) { |
| 2933 ZoneList<Expression*>* args = expr->arguments(); |
| 2926 ASSERT(args->length() == 2); | 2934 ASSERT(args->length() == 2); |
| 2927 | |
| 2928 VisitForStackValue(args->at(0)); // Load the object. | 2935 VisitForStackValue(args->at(0)); // Load the object. |
| 2929 VisitForAccumulatorValue(args->at(1)); // Load the value. | 2936 VisitForAccumulatorValue(args->at(1)); // Load the value. |
| 2930 __ pop(r1); // r0 = value. r1 = object. | 2937 __ pop(r1); // r0 = value. r1 = object. |
| 2931 | 2938 |
| 2932 Label done; | 2939 Label done; |
| 2933 // If the object is a smi, return the value. | 2940 // If the object is a smi, return the value. |
| 2934 __ JumpIfSmi(r1, &done); | 2941 __ JumpIfSmi(r1, &done); |
| 2935 | 2942 |
| 2936 // If the object is not a value type, return the value. | 2943 // If the object is not a value type, return the value. |
| 2937 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); | 2944 __ CompareObjectType(r1, r2, r2, JS_VALUE_TYPE); |
| 2938 __ b(ne, &done); | 2945 __ b(ne, &done); |
| 2939 | 2946 |
| 2940 // Store the value. | 2947 // Store the value. |
| 2941 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); | 2948 __ str(r0, FieldMemOperand(r1, JSValue::kValueOffset)); |
| 2942 // Update the write barrier. Save the value as it will be | 2949 // Update the write barrier. Save the value as it will be |
| 2943 // overwritten by the write barrier code and is needed afterward. | 2950 // overwritten by the write barrier code and is needed afterward. |
| 2944 __ mov(r2, r0); | 2951 __ mov(r2, r0); |
| 2945 __ RecordWriteField( | 2952 __ RecordWriteField( |
| 2946 r1, JSValue::kValueOffset, r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); | 2953 r1, JSValue::kValueOffset, r2, r3, kLRHasBeenSaved, kDontSaveFPRegs); |
| 2947 | 2954 |
| 2948 __ bind(&done); | 2955 __ bind(&done); |
| 2949 context()->Plug(r0); | 2956 context()->Plug(r0); |
| 2950 } | 2957 } |
| 2951 | 2958 |
| 2952 | 2959 |
| 2953 void FullCodeGenerator::EmitNumberToString(ZoneList<Expression*>* args) { | 2960 void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) { |
| 2961 ZoneList<Expression*>* args = expr->arguments(); |
| 2954 ASSERT_EQ(args->length(), 1); | 2962 ASSERT_EQ(args->length(), 1); |
| 2955 | |
| 2956 // Load the argument on the stack and call the stub. | 2963 // Load the argument on the stack and call the stub. |
| 2957 VisitForStackValue(args->at(0)); | 2964 VisitForStackValue(args->at(0)); |
| 2958 | 2965 |
| 2959 NumberToStringStub stub; | 2966 NumberToStringStub stub; |
| 2960 __ CallStub(&stub); | 2967 __ CallStub(&stub); |
| 2961 context()->Plug(r0); | 2968 context()->Plug(r0); |
| 2962 } | 2969 } |
| 2963 | 2970 |
| 2964 | 2971 |
| 2965 void FullCodeGenerator::EmitStringCharFromCode(ZoneList<Expression*>* args) { | 2972 void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) { |
| 2973 ZoneList<Expression*>* args = expr->arguments(); |
| 2966 ASSERT(args->length() == 1); | 2974 ASSERT(args->length() == 1); |
| 2967 | |
| 2968 VisitForAccumulatorValue(args->at(0)); | 2975 VisitForAccumulatorValue(args->at(0)); |
| 2969 | 2976 |
| 2970 Label done; | 2977 Label done; |
| 2971 StringCharFromCodeGenerator generator(r0, r1); | 2978 StringCharFromCodeGenerator generator(r0, r1); |
| 2972 generator.GenerateFast(masm_); | 2979 generator.GenerateFast(masm_); |
| 2973 __ jmp(&done); | 2980 __ jmp(&done); |
| 2974 | 2981 |
| 2975 NopRuntimeCallHelper call_helper; | 2982 NopRuntimeCallHelper call_helper; |
| 2976 generator.GenerateSlow(masm_, call_helper); | 2983 generator.GenerateSlow(masm_, call_helper); |
| 2977 | 2984 |
| 2978 __ bind(&done); | 2985 __ bind(&done); |
| 2979 context()->Plug(r1); | 2986 context()->Plug(r1); |
| 2980 } | 2987 } |
| 2981 | 2988 |
| 2982 | 2989 |
| 2983 void FullCodeGenerator::EmitStringCharCodeAt(ZoneList<Expression*>* args) { | 2990 void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) { |
| 2991 ZoneList<Expression*>* args = expr->arguments(); |
| 2984 ASSERT(args->length() == 2); | 2992 ASSERT(args->length() == 2); |
| 2985 | |
| 2986 VisitForStackValue(args->at(0)); | 2993 VisitForStackValue(args->at(0)); |
| 2987 VisitForAccumulatorValue(args->at(1)); | 2994 VisitForAccumulatorValue(args->at(1)); |
| 2988 | 2995 |
| 2989 Register object = r1; | 2996 Register object = r1; |
| 2990 Register index = r0; | 2997 Register index = r0; |
| 2991 Register scratch = r2; | 2998 Register scratch = r2; |
| 2992 Register result = r3; | 2999 Register result = r3; |
| 2993 | 3000 |
| 2994 __ pop(object); | 3001 __ pop(object); |
| 2995 | 3002 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3020 __ jmp(&done); | 3027 __ jmp(&done); |
| 3021 | 3028 |
| 3022 NopRuntimeCallHelper call_helper; | 3029 NopRuntimeCallHelper call_helper; |
| 3023 generator.GenerateSlow(masm_, call_helper); | 3030 generator.GenerateSlow(masm_, call_helper); |
| 3024 | 3031 |
| 3025 __ bind(&done); | 3032 __ bind(&done); |
| 3026 context()->Plug(result); | 3033 context()->Plug(result); |
| 3027 } | 3034 } |
| 3028 | 3035 |
| 3029 | 3036 |
| 3030 void FullCodeGenerator::EmitStringCharAt(ZoneList<Expression*>* args) { | 3037 void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) { |
| 3038 ZoneList<Expression*>* args = expr->arguments(); |
| 3031 ASSERT(args->length() == 2); | 3039 ASSERT(args->length() == 2); |
| 3032 | |
| 3033 VisitForStackValue(args->at(0)); | 3040 VisitForStackValue(args->at(0)); |
| 3034 VisitForAccumulatorValue(args->at(1)); | 3041 VisitForAccumulatorValue(args->at(1)); |
| 3035 | 3042 |
| 3036 Register object = r1; | 3043 Register object = r1; |
| 3037 Register index = r0; | 3044 Register index = r0; |
| 3038 Register scratch1 = r2; | 3045 Register scratch1 = r2; |
| 3039 Register scratch2 = r3; | 3046 Register scratch2 = r3; |
| 3040 Register result = r0; | 3047 Register result = r0; |
| 3041 | 3048 |
| 3042 __ pop(object); | 3049 __ pop(object); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3069 __ jmp(&done); | 3076 __ jmp(&done); |
| 3070 | 3077 |
| 3071 NopRuntimeCallHelper call_helper; | 3078 NopRuntimeCallHelper call_helper; |
| 3072 generator.GenerateSlow(masm_, call_helper); | 3079 generator.GenerateSlow(masm_, call_helper); |
| 3073 | 3080 |
| 3074 __ bind(&done); | 3081 __ bind(&done); |
| 3075 context()->Plug(result); | 3082 context()->Plug(result); |
| 3076 } | 3083 } |
| 3077 | 3084 |
| 3078 | 3085 |
| 3079 void FullCodeGenerator::EmitStringAdd(ZoneList<Expression*>* args) { | 3086 void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) { |
| 3087 ZoneList<Expression*>* args = expr->arguments(); |
| 3080 ASSERT_EQ(2, args->length()); | 3088 ASSERT_EQ(2, args->length()); |
| 3081 | |
| 3082 VisitForStackValue(args->at(0)); | 3089 VisitForStackValue(args->at(0)); |
| 3083 VisitForStackValue(args->at(1)); | 3090 VisitForStackValue(args->at(1)); |
| 3084 | 3091 |
| 3085 StringAddStub stub(NO_STRING_ADD_FLAGS); | 3092 StringAddStub stub(NO_STRING_ADD_FLAGS); |
| 3086 __ CallStub(&stub); | 3093 __ CallStub(&stub); |
| 3087 context()->Plug(r0); | 3094 context()->Plug(r0); |
| 3088 } | 3095 } |
| 3089 | 3096 |
| 3090 | 3097 |
| 3091 void FullCodeGenerator::EmitStringCompare(ZoneList<Expression*>* args) { | 3098 void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) { |
| 3099 ZoneList<Expression*>* args = expr->arguments(); |
| 3092 ASSERT_EQ(2, args->length()); | 3100 ASSERT_EQ(2, args->length()); |
| 3093 | |
| 3094 VisitForStackValue(args->at(0)); | 3101 VisitForStackValue(args->at(0)); |
| 3095 VisitForStackValue(args->at(1)); | 3102 VisitForStackValue(args->at(1)); |
| 3096 | 3103 |
| 3097 StringCompareStub stub; | 3104 StringCompareStub stub; |
| 3098 __ CallStub(&stub); | 3105 __ CallStub(&stub); |
| 3099 context()->Plug(r0); | 3106 context()->Plug(r0); |
| 3100 } | 3107 } |
| 3101 | 3108 |
| 3102 | 3109 |
| 3103 void FullCodeGenerator::EmitMathSin(ZoneList<Expression*>* args) { | 3110 void FullCodeGenerator::EmitMathSin(CallRuntime* expr) { |
| 3104 // Load the argument on the stack and call the stub. | 3111 // Load the argument on the stack and call the stub. |
| 3105 TranscendentalCacheStub stub(TranscendentalCache::SIN, | 3112 TranscendentalCacheStub stub(TranscendentalCache::SIN, |
| 3106 TranscendentalCacheStub::TAGGED); | 3113 TranscendentalCacheStub::TAGGED); |
| 3114 ZoneList<Expression*>* args = expr->arguments(); |
| 3107 ASSERT(args->length() == 1); | 3115 ASSERT(args->length() == 1); |
| 3108 VisitForStackValue(args->at(0)); | 3116 VisitForStackValue(args->at(0)); |
| 3109 __ CallStub(&stub); | 3117 __ CallStub(&stub); |
| 3110 context()->Plug(r0); | 3118 context()->Plug(r0); |
| 3111 } | 3119 } |
| 3112 | 3120 |
| 3113 | 3121 |
| 3114 void FullCodeGenerator::EmitMathCos(ZoneList<Expression*>* args) { | 3122 void FullCodeGenerator::EmitMathCos(CallRuntime* expr) { |
| 3115 // Load the argument on the stack and call the stub. | 3123 // Load the argument on the stack and call the stub. |
| 3116 TranscendentalCacheStub stub(TranscendentalCache::COS, | 3124 TranscendentalCacheStub stub(TranscendentalCache::COS, |
| 3117 TranscendentalCacheStub::TAGGED); | 3125 TranscendentalCacheStub::TAGGED); |
| 3126 ZoneList<Expression*>* args = expr->arguments(); |
| 3118 ASSERT(args->length() == 1); | 3127 ASSERT(args->length() == 1); |
| 3119 VisitForStackValue(args->at(0)); | 3128 VisitForStackValue(args->at(0)); |
| 3120 __ CallStub(&stub); | 3129 __ CallStub(&stub); |
| 3121 context()->Plug(r0); | 3130 context()->Plug(r0); |
| 3122 } | 3131 } |
| 3123 | 3132 |
| 3124 | 3133 |
| 3125 void FullCodeGenerator::EmitMathLog(ZoneList<Expression*>* args) { | 3134 void FullCodeGenerator::EmitMathLog(CallRuntime* expr) { |
| 3126 // Load the argument on the stack and call the stub. | 3135 // Load the argument on the stack and call the stub. |
| 3127 TranscendentalCacheStub stub(TranscendentalCache::LOG, | 3136 TranscendentalCacheStub stub(TranscendentalCache::LOG, |
| 3128 TranscendentalCacheStub::TAGGED); | 3137 TranscendentalCacheStub::TAGGED); |
| 3138 ZoneList<Expression*>* args = expr->arguments(); |
| 3129 ASSERT(args->length() == 1); | 3139 ASSERT(args->length() == 1); |
| 3130 VisitForStackValue(args->at(0)); | 3140 VisitForStackValue(args->at(0)); |
| 3131 __ CallStub(&stub); | 3141 __ CallStub(&stub); |
| 3132 context()->Plug(r0); | 3142 context()->Plug(r0); |
| 3133 } | 3143 } |
| 3134 | 3144 |
| 3135 | 3145 |
| 3136 void FullCodeGenerator::EmitMathSqrt(ZoneList<Expression*>* args) { | 3146 void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) { |
| 3137 // Load the argument on the stack and call the runtime function. | 3147 // Load the argument on the stack and call the runtime function. |
| 3148 ZoneList<Expression*>* args = expr->arguments(); |
| 3138 ASSERT(args->length() == 1); | 3149 ASSERT(args->length() == 1); |
| 3139 VisitForStackValue(args->at(0)); | 3150 VisitForStackValue(args->at(0)); |
| 3140 __ CallRuntime(Runtime::kMath_sqrt, 1); | 3151 __ CallRuntime(Runtime::kMath_sqrt, 1); |
| 3141 context()->Plug(r0); | 3152 context()->Plug(r0); |
| 3142 } | 3153 } |
| 3143 | 3154 |
| 3144 | 3155 |
| 3145 void FullCodeGenerator::EmitCallFunction(ZoneList<Expression*>* args) { | 3156 void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) { |
| 3157 ZoneList<Expression*>* args = expr->arguments(); |
| 3146 ASSERT(args->length() >= 2); | 3158 ASSERT(args->length() >= 2); |
| 3147 | 3159 |
| 3148 int arg_count = args->length() - 2; // 2 ~ receiver and function. | 3160 int arg_count = args->length() - 2; // 2 ~ receiver and function. |
| 3149 for (int i = 0; i < arg_count + 1; i++) { | 3161 for (int i = 0; i < arg_count + 1; i++) { |
| 3150 VisitForStackValue(args->at(i)); | 3162 VisitForStackValue(args->at(i)); |
| 3151 } | 3163 } |
| 3152 VisitForAccumulatorValue(args->last()); // Function. | 3164 VisitForAccumulatorValue(args->last()); // Function. |
| 3153 | 3165 |
| 3154 // InvokeFunction requires the function in r1. Move it in there. | 3166 // InvokeFunction requires the function in r1. Move it in there. |
| 3155 __ mov(r1, result_register()); | 3167 __ mov(r1, result_register()); |
| 3156 ParameterCount count(arg_count); | 3168 ParameterCount count(arg_count); |
| 3157 __ InvokeFunction(r1, count, CALL_FUNCTION, | 3169 __ InvokeFunction(r1, count, CALL_FUNCTION, |
| 3158 NullCallWrapper(), CALL_AS_METHOD); | 3170 NullCallWrapper(), CALL_AS_METHOD); |
| 3159 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3171 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3160 context()->Plug(r0); | 3172 context()->Plug(r0); |
| 3161 } | 3173 } |
| 3162 | 3174 |
| 3163 | 3175 |
| 3164 void FullCodeGenerator::EmitRegExpConstructResult(ZoneList<Expression*>* args) { | 3176 void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) { |
| 3165 RegExpConstructResultStub stub; | 3177 RegExpConstructResultStub stub; |
| 3178 ZoneList<Expression*>* args = expr->arguments(); |
| 3166 ASSERT(args->length() == 3); | 3179 ASSERT(args->length() == 3); |
| 3167 VisitForStackValue(args->at(0)); | 3180 VisitForStackValue(args->at(0)); |
| 3168 VisitForStackValue(args->at(1)); | 3181 VisitForStackValue(args->at(1)); |
| 3169 VisitForStackValue(args->at(2)); | 3182 VisitForStackValue(args->at(2)); |
| 3170 __ CallStub(&stub); | 3183 __ CallStub(&stub); |
| 3171 context()->Plug(r0); | 3184 context()->Plug(r0); |
| 3172 } | 3185 } |
| 3173 | 3186 |
| 3174 | 3187 |
| 3175 void FullCodeGenerator::EmitSwapElements(ZoneList<Expression*>* args) { | 3188 void FullCodeGenerator::EmitSwapElements(CallRuntime* expr) { |
| 3189 ZoneList<Expression*>* args = expr->arguments(); |
| 3176 ASSERT(args->length() == 3); | 3190 ASSERT(args->length() == 3); |
| 3177 VisitForStackValue(args->at(0)); | 3191 VisitForStackValue(args->at(0)); |
| 3178 VisitForStackValue(args->at(1)); | 3192 VisitForStackValue(args->at(1)); |
| 3179 VisitForStackValue(args->at(2)); | 3193 VisitForStackValue(args->at(2)); |
| 3180 Label done; | 3194 Label done; |
| 3181 Label slow_case; | 3195 Label slow_case; |
| 3182 Register object = r0; | 3196 Register object = r0; |
| 3183 Register index1 = r1; | 3197 Register index1 = r1; |
| 3184 Register index2 = r2; | 3198 Register index2 = r2; |
| 3185 Register elements = r3; | 3199 Register elements = r3; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3262 __ jmp(&done); | 3276 __ jmp(&done); |
| 3263 | 3277 |
| 3264 __ bind(&slow_case); | 3278 __ bind(&slow_case); |
| 3265 __ CallRuntime(Runtime::kSwapElements, 3); | 3279 __ CallRuntime(Runtime::kSwapElements, 3); |
| 3266 | 3280 |
| 3267 __ bind(&done); | 3281 __ bind(&done); |
| 3268 context()->Plug(r0); | 3282 context()->Plug(r0); |
| 3269 } | 3283 } |
| 3270 | 3284 |
| 3271 | 3285 |
| 3272 void FullCodeGenerator::EmitGetFromCache(ZoneList<Expression*>* args) { | 3286 void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) { |
| 3287 ZoneList<Expression*>* args = expr->arguments(); |
| 3273 ASSERT_EQ(2, args->length()); | 3288 ASSERT_EQ(2, args->length()); |
| 3274 | |
| 3275 ASSERT_NE(NULL, args->at(0)->AsLiteral()); | 3289 ASSERT_NE(NULL, args->at(0)->AsLiteral()); |
| 3276 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); | 3290 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); |
| 3277 | 3291 |
| 3278 Handle<FixedArray> jsfunction_result_caches( | 3292 Handle<FixedArray> jsfunction_result_caches( |
| 3279 isolate()->global_context()->jsfunction_result_caches()); | 3293 isolate()->global_context()->jsfunction_result_caches()); |
| 3280 if (jsfunction_result_caches->length() <= cache_id) { | 3294 if (jsfunction_result_caches->length() <= cache_id) { |
| 3281 __ Abort("Attempt to use undefined cache."); | 3295 __ Abort("Attempt to use undefined cache."); |
| 3282 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 3296 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 3283 context()->Plug(r0); | 3297 context()->Plug(r0); |
| 3284 return; | 3298 return; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3313 __ bind(¬_found); | 3327 __ bind(¬_found); |
| 3314 // Call runtime to perform the lookup. | 3328 // Call runtime to perform the lookup. |
| 3315 __ Push(cache, key); | 3329 __ Push(cache, key); |
| 3316 __ CallRuntime(Runtime::kGetFromCache, 2); | 3330 __ CallRuntime(Runtime::kGetFromCache, 2); |
| 3317 | 3331 |
| 3318 __ bind(&done); | 3332 __ bind(&done); |
| 3319 context()->Plug(r0); | 3333 context()->Plug(r0); |
| 3320 } | 3334 } |
| 3321 | 3335 |
| 3322 | 3336 |
| 3323 void FullCodeGenerator::EmitIsRegExpEquivalent(ZoneList<Expression*>* args) { | 3337 void FullCodeGenerator::EmitIsRegExpEquivalent(CallRuntime* expr) { |
| 3338 ZoneList<Expression*>* args = expr->arguments(); |
| 3324 ASSERT_EQ(2, args->length()); | 3339 ASSERT_EQ(2, args->length()); |
| 3325 | 3340 |
| 3326 Register right = r0; | 3341 Register right = r0; |
| 3327 Register left = r1; | 3342 Register left = r1; |
| 3328 Register tmp = r2; | 3343 Register tmp = r2; |
| 3329 Register tmp2 = r3; | 3344 Register tmp2 = r3; |
| 3330 | 3345 |
| 3331 VisitForStackValue(args->at(0)); | 3346 VisitForStackValue(args->at(0)); |
| 3332 VisitForAccumulatorValue(args->at(1)); | 3347 VisitForAccumulatorValue(args->at(1)); |
| 3333 __ pop(left); | 3348 __ pop(left); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3353 __ LoadRoot(r0, Heap::kFalseValueRootIndex); | 3368 __ LoadRoot(r0, Heap::kFalseValueRootIndex); |
| 3354 __ jmp(&done); | 3369 __ jmp(&done); |
| 3355 __ bind(&ok); | 3370 __ bind(&ok); |
| 3356 __ LoadRoot(r0, Heap::kTrueValueRootIndex); | 3371 __ LoadRoot(r0, Heap::kTrueValueRootIndex); |
| 3357 __ bind(&done); | 3372 __ bind(&done); |
| 3358 | 3373 |
| 3359 context()->Plug(r0); | 3374 context()->Plug(r0); |
| 3360 } | 3375 } |
| 3361 | 3376 |
| 3362 | 3377 |
| 3363 void FullCodeGenerator::EmitHasCachedArrayIndex(ZoneList<Expression*>* args) { | 3378 void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) { |
| 3379 ZoneList<Expression*>* args = expr->arguments(); |
| 3364 VisitForAccumulatorValue(args->at(0)); | 3380 VisitForAccumulatorValue(args->at(0)); |
| 3365 | 3381 |
| 3366 Label materialize_true, materialize_false; | 3382 Label materialize_true, materialize_false; |
| 3367 Label* if_true = NULL; | 3383 Label* if_true = NULL; |
| 3368 Label* if_false = NULL; | 3384 Label* if_false = NULL; |
| 3369 Label* fall_through = NULL; | 3385 Label* fall_through = NULL; |
| 3370 context()->PrepareTest(&materialize_true, &materialize_false, | 3386 context()->PrepareTest(&materialize_true, &materialize_false, |
| 3371 &if_true, &if_false, &fall_through); | 3387 &if_true, &if_false, &fall_through); |
| 3372 | 3388 |
| 3373 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset)); | 3389 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset)); |
| 3374 __ tst(r0, Operand(String::kContainsCachedArrayIndexMask)); | 3390 __ tst(r0, Operand(String::kContainsCachedArrayIndexMask)); |
| 3375 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 3391 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 3376 Split(eq, if_true, if_false, fall_through); | 3392 Split(eq, if_true, if_false, fall_through); |
| 3377 | 3393 |
| 3378 context()->Plug(if_true, if_false); | 3394 context()->Plug(if_true, if_false); |
| 3379 } | 3395 } |
| 3380 | 3396 |
| 3381 | 3397 |
| 3382 void FullCodeGenerator::EmitGetCachedArrayIndex(ZoneList<Expression*>* args) { | 3398 void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) { |
| 3399 ZoneList<Expression*>* args = expr->arguments(); |
| 3383 ASSERT(args->length() == 1); | 3400 ASSERT(args->length() == 1); |
| 3384 VisitForAccumulatorValue(args->at(0)); | 3401 VisitForAccumulatorValue(args->at(0)); |
| 3385 | 3402 |
| 3386 if (FLAG_debug_code) { | 3403 if (FLAG_debug_code) { |
| 3387 __ AbortIfNotString(r0); | 3404 __ AbortIfNotString(r0); |
| 3388 } | 3405 } |
| 3389 | 3406 |
| 3390 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset)); | 3407 __ ldr(r0, FieldMemOperand(r0, String::kHashFieldOffset)); |
| 3391 __ IndexFromHash(r0, r0); | 3408 __ IndexFromHash(r0, r0); |
| 3392 | 3409 |
| 3393 context()->Plug(r0); | 3410 context()->Plug(r0); |
| 3394 } | 3411 } |
| 3395 | 3412 |
| 3396 | 3413 |
| 3397 void FullCodeGenerator::EmitFastAsciiArrayJoin(ZoneList<Expression*>* args) { | 3414 void FullCodeGenerator::EmitFastAsciiArrayJoin(CallRuntime* expr) { |
| 3398 Label bailout, done, one_char_separator, long_separator, | 3415 Label bailout, done, one_char_separator, long_separator, |
| 3399 non_trivial_array, not_size_one_array, loop, | 3416 non_trivial_array, not_size_one_array, loop, |
| 3400 empty_separator_loop, one_char_separator_loop, | 3417 empty_separator_loop, one_char_separator_loop, |
| 3401 one_char_separator_loop_entry, long_separator_loop; | 3418 one_char_separator_loop_entry, long_separator_loop; |
| 3402 | 3419 ZoneList<Expression*>* args = expr->arguments(); |
| 3403 ASSERT(args->length() == 2); | 3420 ASSERT(args->length() == 2); |
| 3404 VisitForStackValue(args->at(1)); | 3421 VisitForStackValue(args->at(1)); |
| 3405 VisitForAccumulatorValue(args->at(0)); | 3422 VisitForAccumulatorValue(args->at(0)); |
| 3406 | 3423 |
| 3407 // All aliases of the same register have disjoint lifetimes. | 3424 // All aliases of the same register have disjoint lifetimes. |
| 3408 Register array = r0; | 3425 Register array = r0; |
| 3409 Register elements = no_reg; // Will be r0. | 3426 Register elements = no_reg; // Will be r0. |
| 3410 Register result = no_reg; // Will be r0. | 3427 Register result = no_reg; // Will be r0. |
| 3411 Register separator = r1; | 3428 Register separator = r1; |
| 3412 Register array_length = r2; | 3429 Register array_length = r2; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3720 context()->Plug(Heap::kUndefinedValueRootIndex); | 3737 context()->Plug(Heap::kUndefinedValueRootIndex); |
| 3721 break; | 3738 break; |
| 3722 } | 3739 } |
| 3723 | 3740 |
| 3724 case Token::NOT: { | 3741 case Token::NOT: { |
| 3725 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); | 3742 Comment cmnt(masm_, "[ UnaryOperation (NOT)"); |
| 3726 if (context()->IsEffect()) { | 3743 if (context()->IsEffect()) { |
| 3727 // Unary NOT has no side effects so it's only necessary to visit the | 3744 // Unary NOT has no side effects so it's only necessary to visit the |
| 3728 // subexpression. Match the optimizing compiler by not branching. | 3745 // subexpression. Match the optimizing compiler by not branching. |
| 3729 VisitForEffect(expr->expression()); | 3746 VisitForEffect(expr->expression()); |
| 3747 } else if (context()->IsTest()) { |
| 3748 const TestContext* test = TestContext::cast(context()); |
| 3749 // The labels are swapped for the recursive call. |
| 3750 VisitForControl(expr->expression(), |
| 3751 test->false_label(), |
| 3752 test->true_label(), |
| 3753 test->fall_through()); |
| 3754 context()->Plug(test->true_label(), test->false_label()); |
| 3730 } else { | 3755 } else { |
| 3731 Label materialize_true, materialize_false; | 3756 // We handle value contexts explicitly rather than simply visiting |
| 3732 Label* if_true = NULL; | 3757 // for control and plugging the control flow into the context, |
| 3733 Label* if_false = NULL; | 3758 // because we need to prepare a pair of extra administrative AST ids |
| 3734 Label* fall_through = NULL; | 3759 // for the optimizing compiler. |
| 3735 | 3760 ASSERT(context()->IsAccumulatorValue() || context()->IsStackValue()); |
| 3736 // Notice that the labels are swapped. | 3761 Label materialize_true, materialize_false, done; |
| 3737 context()->PrepareTest(&materialize_true, &materialize_false, | 3762 VisitForControl(expr->expression(), |
| 3738 &if_false, &if_true, &fall_through); | 3763 &materialize_false, |
| 3739 if (context()->IsTest()) ForwardBailoutToChild(expr); | 3764 &materialize_true, |
| 3740 VisitForControl(expr->expression(), if_true, if_false, fall_through); | 3765 &materialize_true); |
| 3741 context()->Plug(if_false, if_true); // Labels swapped. | 3766 __ bind(&materialize_true); |
| 3767 PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS); |
| 3768 __ LoadRoot(r0, Heap::kTrueValueRootIndex); |
| 3769 if (context()->IsStackValue()) __ push(r0); |
| 3770 __ jmp(&done); |
| 3771 __ bind(&materialize_false); |
| 3772 PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS); |
| 3773 __ LoadRoot(r0, Heap::kFalseValueRootIndex); |
| 3774 if (context()->IsStackValue()) __ push(r0); |
| 3775 __ bind(&done); |
| 3742 } | 3776 } |
| 3743 break; | 3777 break; |
| 3744 } | 3778 } |
| 3745 | 3779 |
| 3746 case Token::TYPEOF: { | 3780 case Token::TYPEOF: { |
| 3747 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 3781 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
| 3748 { StackValueContext context(this); | 3782 { StackValueContext context(this); |
| 3749 VisitForTypeofValue(expr->expression()); | 3783 VisitForTypeofValue(expr->expression()); |
| 3750 } | 3784 } |
| 3751 __ CallRuntime(Runtime::kTypeof, 1); | 3785 __ CallRuntime(Runtime::kTypeof, 1); |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3990 __ bind(&slow); | 4024 __ bind(&slow); |
| 3991 __ mov(r0, Operand(proxy->name())); | 4025 __ mov(r0, Operand(proxy->name())); |
| 3992 __ Push(cp, r0); | 4026 __ Push(cp, r0); |
| 3993 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 4027 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
| 3994 PrepareForBailout(expr, TOS_REG); | 4028 PrepareForBailout(expr, TOS_REG); |
| 3995 __ bind(&done); | 4029 __ bind(&done); |
| 3996 | 4030 |
| 3997 context()->Plug(r0); | 4031 context()->Plug(r0); |
| 3998 } else { | 4032 } else { |
| 3999 // This expression cannot throw a reference error at the top level. | 4033 // This expression cannot throw a reference error at the top level. |
| 4000 VisitInCurrentContext(expr); | 4034 VisitInDuplicateContext(expr); |
| 4001 } | 4035 } |
| 4002 } | 4036 } |
| 4003 | 4037 |
| 4004 | 4038 |
| 4005 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 4039 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
| 4040 Expression* sub_expr, |
| 4006 Handle<String> check) { | 4041 Handle<String> check) { |
| 4007 Label materialize_true, materialize_false; | 4042 Label materialize_true, materialize_false; |
| 4008 Label* if_true = NULL; | 4043 Label* if_true = NULL; |
| 4009 Label* if_false = NULL; | 4044 Label* if_false = NULL; |
| 4010 Label* fall_through = NULL; | 4045 Label* fall_through = NULL; |
| 4011 context()->PrepareTest(&materialize_true, &materialize_false, | 4046 context()->PrepareTest(&materialize_true, &materialize_false, |
| 4012 &if_true, &if_false, &fall_through); | 4047 &if_true, &if_false, &fall_through); |
| 4013 | 4048 |
| 4014 { AccumulatorValueContext context(this); | 4049 { AccumulatorValueContext context(this); |
| 4015 VisitForTypeofValue(expr); | 4050 VisitForTypeofValue(sub_expr); |
| 4016 } | 4051 } |
| 4017 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4052 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4018 | 4053 |
| 4019 if (check->Equals(isolate()->heap()->number_symbol())) { | 4054 if (check->Equals(isolate()->heap()->number_symbol())) { |
| 4020 __ JumpIfSmi(r0, if_true); | 4055 __ JumpIfSmi(r0, if_true); |
| 4021 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); | 4056 __ ldr(r0, FieldMemOperand(r0, HeapObject::kMapOffset)); |
| 4022 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 4057 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| 4023 __ cmp(r0, ip); | 4058 __ cmp(r0, ip); |
| 4024 Split(eq, if_true, if_false, fall_through); | 4059 Split(eq, if_true, if_false, fall_through); |
| 4025 } else if (check->Equals(isolate()->heap()->string_symbol())) { | 4060 } else if (check->Equals(isolate()->heap()->string_symbol())) { |
| 4026 __ JumpIfSmi(r0, if_false); | 4061 __ JumpIfSmi(r0, if_false); |
| 4027 // Check for undetectable objects => false. | 4062 // Check for undetectable objects => false. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4094 Label* fall_through = NULL; | 4129 Label* fall_through = NULL; |
| 4095 context()->PrepareTest(&materialize_true, &materialize_false, | 4130 context()->PrepareTest(&materialize_true, &materialize_false, |
| 4096 &if_true, &if_false, &fall_through); | 4131 &if_true, &if_false, &fall_through); |
| 4097 | 4132 |
| 4098 Token::Value op = expr->op(); | 4133 Token::Value op = expr->op(); |
| 4099 VisitForStackValue(expr->left()); | 4134 VisitForStackValue(expr->left()); |
| 4100 switch (op) { | 4135 switch (op) { |
| 4101 case Token::IN: | 4136 case Token::IN: |
| 4102 VisitForStackValue(expr->right()); | 4137 VisitForStackValue(expr->right()); |
| 4103 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); | 4138 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION); |
| 4104 PrepareForBailoutBeforeSplit(TOS_REG, false, NULL, NULL); | 4139 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
| 4105 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 4140 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 4106 __ cmp(r0, ip); | 4141 __ cmp(r0, ip); |
| 4107 Split(eq, if_true, if_false, fall_through); | 4142 Split(eq, if_true, if_false, fall_through); |
| 4108 break; | 4143 break; |
| 4109 | 4144 |
| 4110 case Token::INSTANCEOF: { | 4145 case Token::INSTANCEOF: { |
| 4111 VisitForStackValue(expr->right()); | 4146 VisitForStackValue(expr->right()); |
| 4112 InstanceofStub stub(InstanceofStub::kNoFlags); | 4147 InstanceofStub stub(InstanceofStub::kNoFlags); |
| 4113 __ CallStub(&stub); | 4148 __ CallStub(&stub); |
| 4114 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4149 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4115 // The stub returns 0 for true. | 4150 // The stub returns 0 for true. |
| 4116 __ tst(r0, r0); | 4151 __ tst(r0, r0); |
| 4117 Split(eq, if_true, if_false, fall_through); | 4152 Split(eq, if_true, if_false, fall_through); |
| 4118 break; | 4153 break; |
| 4119 } | 4154 } |
| 4120 | 4155 |
| 4121 default: { | 4156 default: { |
| 4122 VisitForAccumulatorValue(expr->right()); | 4157 VisitForAccumulatorValue(expr->right()); |
| 4123 Condition cond = eq; | 4158 Condition cond = eq; |
| 4124 switch (op) { | 4159 switch (op) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4154 __ cmp(r1, r0); | 4189 __ cmp(r1, r0); |
| 4155 Split(cond, if_true, if_false, NULL); | 4190 Split(cond, if_true, if_false, NULL); |
| 4156 __ bind(&slow_case); | 4191 __ bind(&slow_case); |
| 4157 } | 4192 } |
| 4158 | 4193 |
| 4159 // Record position and call the compare IC. | 4194 // Record position and call the compare IC. |
| 4160 SetSourcePosition(expr->position()); | 4195 SetSourcePosition(expr->position()); |
| 4161 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4196 Handle<Code> ic = CompareIC::GetUninitialized(op); |
| 4162 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); | 4197 __ Call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 4163 patch_site.EmitPatchInfo(); | 4198 patch_site.EmitPatchInfo(); |
| 4164 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4199 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4165 __ cmp(r0, Operand(0)); | 4200 __ cmp(r0, Operand(0)); |
| 4166 Split(cond, if_true, if_false, fall_through); | 4201 Split(cond, if_true, if_false, fall_through); |
| 4167 } | 4202 } |
| 4168 } | 4203 } |
| 4169 | 4204 |
| 4170 // Convert the result of the comparison into one expected for this | 4205 // Convert the result of the comparison into one expected for this |
| 4171 // expression's context. | 4206 // expression's context. |
| 4172 context()->Plug(if_true, if_false); | 4207 context()->Plug(if_true, if_false); |
| 4173 } | 4208 } |
| 4174 | 4209 |
| 4175 | 4210 |
| 4176 void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, | 4211 void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr, |
| 4177 Expression* sub_expr, | 4212 Expression* sub_expr, |
| 4178 NilValue nil) { | 4213 NilValue nil) { |
| 4179 Label materialize_true, materialize_false; | 4214 Label materialize_true, materialize_false; |
| 4180 Label* if_true = NULL; | 4215 Label* if_true = NULL; |
| 4181 Label* if_false = NULL; | 4216 Label* if_false = NULL; |
| 4182 Label* fall_through = NULL; | 4217 Label* fall_through = NULL; |
| 4183 context()->PrepareTest(&materialize_true, &materialize_false, | 4218 context()->PrepareTest(&materialize_true, &materialize_false, |
| 4184 &if_true, &if_false, &fall_through); | 4219 &if_true, &if_false, &fall_through); |
| 4185 | 4220 |
| 4186 VisitForAccumulatorValue(sub_expr); | 4221 VisitForAccumulatorValue(sub_expr); |
| 4187 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4222 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 4188 Heap::RootListIndex nil_value = nil == kNullValue ? | 4223 Heap::RootListIndex nil_value = nil == kNullValue ? |
| 4189 Heap::kNullValueRootIndex : | 4224 Heap::kNullValueRootIndex : |
| 4190 Heap::kUndefinedValueRootIndex; | 4225 Heap::kUndefinedValueRootIndex; |
| 4191 __ LoadRoot(r1, nil_value); | 4226 __ LoadRoot(r1, nil_value); |
| 4192 __ cmp(r0, r1); | 4227 __ cmp(r0, r1); |
| 4193 if (expr->op() == Token::EQ_STRICT) { | 4228 if (expr->op() == Token::EQ_STRICT) { |
| 4194 Split(eq, if_true, if_false, fall_through); | 4229 Split(eq, if_true, if_false, fall_through); |
| 4195 } else { | 4230 } else { |
| 4196 Heap::RootListIndex other_nil_value = nil == kNullValue ? | 4231 Heap::RootListIndex other_nil_value = nil == kNullValue ? |
| 4197 Heap::kUndefinedValueRootIndex : | 4232 Heap::kUndefinedValueRootIndex : |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4314 *context_length = 0; | 4349 *context_length = 0; |
| 4315 return previous_; | 4350 return previous_; |
| 4316 } | 4351 } |
| 4317 | 4352 |
| 4318 | 4353 |
| 4319 #undef __ | 4354 #undef __ |
| 4320 | 4355 |
| 4321 } } // namespace v8::internal | 4356 } } // namespace v8::internal |
| 4322 | 4357 |
| 4323 #endif // V8_TARGET_ARCH_ARM | 4358 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |