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

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 6691054: [Arguments] Merge (7442,7496] from bleeding_edge. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/arguments
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/frames-arm.h ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 if (true_label_ != fall_through_) __ b(true_label_); 549 if (true_label_ != fall_through_) __ b(true_label_);
550 } else { 550 } else {
551 if (false_label_ != fall_through_) __ b(false_label_); 551 if (false_label_ != fall_through_) __ b(false_label_);
552 } 552 }
553 } 553 }
554 554
555 555
556 void FullCodeGenerator::DoTest(Label* if_true, 556 void FullCodeGenerator::DoTest(Label* if_true,
557 Label* if_false, 557 Label* if_false,
558 Label* fall_through) { 558 Label* fall_through) {
559 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) { 559 if (CpuFeatures::IsSupported(VFP3)) {
560 CpuFeatures::Scope scope(VFP3); 560 CpuFeatures::Scope scope(VFP3);
561 // Emit the inlined tests assumed by the stub. 561 // Emit the inlined tests assumed by the stub.
562 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 562 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
563 __ cmp(result_register(), ip); 563 __ cmp(result_register(), ip);
564 __ b(eq, if_false); 564 __ b(eq, if_false);
565 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 565 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
566 __ cmp(result_register(), ip); 566 __ cmp(result_register(), ip);
567 __ b(eq, if_true); 567 __ b(eq, if_true);
568 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 568 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
569 __ cmp(result_register(), ip); 569 __ cmp(result_register(), ip);
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 VisitForAccumulatorValue(property->key()); 1514 VisitForAccumulatorValue(property->key());
1515 __ ldr(r1, MemOperand(sp, 0)); 1515 __ ldr(r1, MemOperand(sp, 0));
1516 __ push(r0); 1516 __ push(r0);
1517 } else { 1517 } else {
1518 VisitForStackValue(property->obj()); 1518 VisitForStackValue(property->obj());
1519 VisitForStackValue(property->key()); 1519 VisitForStackValue(property->key());
1520 } 1520 }
1521 break; 1521 break;
1522 } 1522 }
1523 1523
1524 // For compound assignments we need another deoptimization point after the
1525 // variable/property load.
1524 if (expr->is_compound()) { 1526 if (expr->is_compound()) {
1525 { AccumulatorValueContext context(this); 1527 { AccumulatorValueContext context(this);
1526 switch (assign_type) { 1528 switch (assign_type) {
1527 case VARIABLE: 1529 case VARIABLE:
1528 EmitVariableLoad(expr->target()->AsVariableProxy()->var()); 1530 EmitVariableLoad(expr->target()->AsVariableProxy()->var());
1531 PrepareForBailout(expr->target(), TOS_REG);
1529 break; 1532 break;
1530 case NAMED_PROPERTY: 1533 case NAMED_PROPERTY:
1531 EmitNamedPropertyLoad(property); 1534 EmitNamedPropertyLoad(property);
1535 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1532 break; 1536 break;
1533 case KEYED_PROPERTY: 1537 case KEYED_PROPERTY:
1534 EmitKeyedPropertyLoad(property); 1538 EmitKeyedPropertyLoad(property);
1539 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1535 break; 1540 break;
1536 } 1541 }
1537 } 1542 }
1538 1543
1539 // For property compound assignments we need another deoptimization
1540 // point after the property load.
1541 if (property != NULL) {
1542 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1543 }
1544
1545 Token::Value op = expr->binary_op(); 1544 Token::Value op = expr->binary_op();
1546 __ push(r0); // Left operand goes on the stack. 1545 __ push(r0); // Left operand goes on the stack.
1547 VisitForAccumulatorValue(expr->value()); 1546 VisitForAccumulatorValue(expr->value());
1548 1547
1549 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1548 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1550 ? OVERWRITE_RIGHT 1549 ? OVERWRITE_RIGHT
1551 : NO_OVERWRITE; 1550 : NO_OVERWRITE;
1552 SetSourcePosition(expr->position() + 1); 1551 SetSourcePosition(expr->position() + 1);
1553 AccumulatorValueContext context(this); 1552 AccumulatorValueContext context(this);
1554 if (ShouldInlineSmiCase(op)) { 1553 if (ShouldInlineSmiCase(op)) {
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 } 2205 }
2207 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2206 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2208 } else { 2207 } else {
2209 // Call to a keyed property. 2208 // Call to a keyed property.
2210 { PreservePositionScope scope(masm()->positions_recorder()); 2209 { PreservePositionScope scope(masm()->positions_recorder());
2211 VisitForStackValue(prop->obj()); 2210 VisitForStackValue(prop->obj());
2212 } 2211 }
2213 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2212 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2214 } 2213 }
2215 } else { 2214 } else {
2216 // Call to some other expression. If the expression is an anonymous
2217 // function literal not called in a loop, mark it as one that should
2218 // also use the fast code generator.
2219 FunctionLiteral* lit = fun->AsFunctionLiteral();
2220 if (lit != NULL &&
2221 lit->name()->Equals(isolate()->heap()->empty_string()) &&
2222 loop_depth() == 0) {
2223 lit->set_try_full_codegen(true);
2224 }
2225
2226 { PreservePositionScope scope(masm()->positions_recorder()); 2215 { PreservePositionScope scope(masm()->positions_recorder());
2227 VisitForStackValue(fun); 2216 VisitForStackValue(fun);
2228 } 2217 }
2229 // Load global receiver object. 2218 // Load global receiver object.
2230 __ ldr(r1, GlobalObjectOperand()); 2219 __ ldr(r1, GlobalObjectOperand());
2231 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 2220 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
2232 __ push(r1); 2221 __ push(r1);
2233 // Emit function call. 2222 // Emit function call.
2234 EmitCallWithStub(expr); 2223 EmitCallWithStub(expr);
2235 } 2224 }
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2397 2386
2398 VisitForAccumulatorValue(args->at(0)); 2387 VisitForAccumulatorValue(args->at(0));
2399 2388
2400 Label materialize_true, materialize_false; 2389 Label materialize_true, materialize_false;
2401 Label* if_true = NULL; 2390 Label* if_true = NULL;
2402 Label* if_false = NULL; 2391 Label* if_false = NULL;
2403 Label* fall_through = NULL; 2392 Label* fall_through = NULL;
2404 context()->PrepareTest(&materialize_true, &materialize_false, 2393 context()->PrepareTest(&materialize_true, &materialize_false,
2405 &if_true, &if_false, &fall_through); 2394 &if_true, &if_false, &fall_through);
2406 2395
2407 // Just indicate false, as %_IsStringWrapperSafeForDefaultValueOf() is only 2396 if (FLAG_debug_code) __ AbortIfSmi(r0);
2408 // used in a few functions in runtime.js which should not normally be hit by 2397
2409 // this compiler. 2398 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
2399 __ ldrb(ip, FieldMemOperand(r1, Map::kBitField2Offset));
2400 __ tst(ip, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
2401 __ b(ne, if_true);
2402
2403 // Check for fast case object. Generate false result for slow case object.
2404 __ ldr(r2, FieldMemOperand(r0, JSObject::kPropertiesOffset));
2405 __ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset));
2406 __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
2407 __ cmp(r2, ip);
2408 __ b(eq, if_false);
2409
2410 // Look for valueOf symbol in the descriptor array, and indicate false if
2411 // found. The type is not checked, so if it is a transition it is a false
2412 // negative.
2413 __ ldr(r4, FieldMemOperand(r1, Map::kInstanceDescriptorsOffset));
2414 __ ldr(r3, FieldMemOperand(r4, FixedArray::kLengthOffset));
2415 // r4: descriptor array
2416 // r3: length of descriptor array
2417 // Calculate the end of the descriptor array.
2418 STATIC_ASSERT(kSmiTag == 0);
2419 STATIC_ASSERT(kSmiTagSize == 1);
2420 STATIC_ASSERT(kPointerSize == 4);
2421 __ add(r2, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
2422 __ add(r2, r2, Operand(r3, LSL, kPointerSizeLog2 - kSmiTagSize));
2423
2424 // Calculate location of the first key name.
2425 __ add(r4,
2426 r4,
2427 Operand(FixedArray::kHeaderSize - kHeapObjectTag +
2428 DescriptorArray::kFirstIndex * kPointerSize));
2429 // Loop through all the keys in the descriptor array. If one of these is the
2430 // symbol valueOf the result is false.
2431 Label entry, loop;
2432 // The use of ip to store the valueOf symbol asumes that it is not otherwise
2433 // used in the loop below.
2434 __ mov(ip, Operand(FACTORY->value_of_symbol()));
2435 __ jmp(&entry);
2436 __ bind(&loop);
2437 __ ldr(r3, MemOperand(r4, 0));
2438 __ cmp(r3, ip);
2439 __ b(eq, if_false);
2440 __ add(r4, r4, Operand(kPointerSize));
2441 __ bind(&entry);
2442 __ cmp(r4, Operand(r2));
2443 __ b(ne, &loop);
2444
2445 // If a valueOf property is not found on the object check that it's
2446 // prototype is the un-modified String prototype. If not result is false.
2447 __ ldr(r2, FieldMemOperand(r1, Map::kPrototypeOffset));
2448 __ tst(r2, Operand(kSmiTagMask));
2449 __ b(eq, if_false);
2450 __ ldr(r2, FieldMemOperand(r2, HeapObject::kMapOffset));
2451 __ ldr(r3, ContextOperand(cp, Context::GLOBAL_INDEX));
2452 __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalContextOffset));
2453 __ ldr(r3, ContextOperand(r3, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
2454 __ cmp(r2, r3);
2455 __ b(ne, if_false);
2456
2457 // Set the bit in the map to indicate that it has been checked safe for
2458 // default valueOf and set true result.
2459 __ ldrb(r2, FieldMemOperand(r4, Map::kBitField2Offset));
2460 __ orr(r2, r2, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
2461 __ strb(r2, FieldMemOperand(r4, Map::kBitField2Offset));
2462 __ jmp(if_true);
2463
2410 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2464 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2411 __ jmp(if_false);
2412 context()->Plug(if_true, if_false); 2465 context()->Plug(if_true, if_false);
2413 } 2466 }
2414 2467
2415 2468
2416 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { 2469 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
2417 ASSERT(args->length() == 1); 2470 ASSERT(args->length() == 1);
2418 2471
2419 VisitForAccumulatorValue(args->at(0)); 2472 VisitForAccumulatorValue(args->at(0));
2420 2473
2421 Label materialize_true, materialize_false; 2474 Label materialize_true, materialize_false;
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
2656 __ bind(&slow_allocate_heapnumber); 2709 __ bind(&slow_allocate_heapnumber);
2657 // Allocate a heap number. 2710 // Allocate a heap number.
2658 __ CallRuntime(Runtime::kNumberAlloc, 0); 2711 __ CallRuntime(Runtime::kNumberAlloc, 0);
2659 __ mov(r4, Operand(r0)); 2712 __ mov(r4, Operand(r0));
2660 2713
2661 __ bind(&heapnumber_allocated); 2714 __ bind(&heapnumber_allocated);
2662 2715
2663 // Convert 32 random bits in r0 to 0.(32 random bits) in a double 2716 // Convert 32 random bits in r0 to 0.(32 random bits) in a double
2664 // by computing: 2717 // by computing:
2665 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 2718 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
2666 if (isolate()->cpu_features()->IsSupported(VFP3)) { 2719 if (CpuFeatures::IsSupported(VFP3)) {
2667 __ PrepareCallCFunction(0, r1); 2720 __ PrepareCallCFunction(1, r0);
2668 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 0); 2721 __ mov(r0, Operand(ExternalReference::isolate_address()));
2722 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
2669 2723
2670 CpuFeatures::Scope scope(VFP3); 2724 CpuFeatures::Scope scope(VFP3);
2671 // 0x41300000 is the top half of 1.0 x 2^20 as a double. 2725 // 0x41300000 is the top half of 1.0 x 2^20 as a double.
2672 // Create this constant using mov/orr to avoid PC relative load. 2726 // Create this constant using mov/orr to avoid PC relative load.
2673 __ mov(r1, Operand(0x41000000)); 2727 __ mov(r1, Operand(0x41000000));
2674 __ orr(r1, r1, Operand(0x300000)); 2728 __ orr(r1, r1, Operand(0x300000));
2675 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. 2729 // Move 0x41300000xxxxxxxx (x = random bits) to VFP.
2676 __ vmov(d7, r0, r1); 2730 __ vmov(d7, r0, r1);
2677 // Move 0x4130000000000000 to VFP. 2731 // Move 0x4130000000000000 to VFP.
2678 __ mov(r0, Operand(0, RelocInfo::NONE)); 2732 __ mov(r0, Operand(0, RelocInfo::NONE));
2679 __ vmov(d8, r0, r1); 2733 __ vmov(d8, r0, r1);
2680 // Subtract and store the result in the heap number. 2734 // Subtract and store the result in the heap number.
2681 __ vsub(d7, d7, d8); 2735 __ vsub(d7, d7, d8);
2682 __ sub(r0, r4, Operand(kHeapObjectTag)); 2736 __ sub(r0, r4, Operand(kHeapObjectTag));
2683 __ vstr(d7, r0, HeapNumber::kValueOffset); 2737 __ vstr(d7, r0, HeapNumber::kValueOffset);
2684 __ mov(r0, r4); 2738 __ mov(r0, r4);
2685 } else { 2739 } else {
2740 __ PrepareCallCFunction(2, r0);
2686 __ mov(r0, Operand(r4)); 2741 __ mov(r0, Operand(r4));
2687 __ PrepareCallCFunction(1, r1); 2742 __ mov(r1, Operand(ExternalReference::isolate_address()));
2688 __ CallCFunction( 2743 __ CallCFunction(
2689 ExternalReference::fill_heap_number_with_random_function(isolate()), 1); 2744 ExternalReference::fill_heap_number_with_random_function(isolate()), 2);
2690 } 2745 }
2691 2746
2692 context()->Plug(r0); 2747 context()->Plug(r0);
2693 } 2748 }
2694 2749
2695 2750
2696 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) { 2751 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) {
2697 // Load the arguments on the stack and call the stub. 2752 // Load the arguments on the stack and call the stub.
2698 SubStringStub stub; 2753 SubStringStub stub;
2699 ASSERT(args->length() == 3); 2754 ASSERT(args->length() == 3);
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
3668 VisitForStackValue(prop->obj()); 3723 VisitForStackValue(prop->obj());
3669 VisitForAccumulatorValue(prop->key()); 3724 VisitForAccumulatorValue(prop->key());
3670 __ ldr(r1, MemOperand(sp, 0)); 3725 __ ldr(r1, MemOperand(sp, 0));
3671 __ push(r0); 3726 __ push(r0);
3672 EmitKeyedPropertyLoad(prop); 3727 EmitKeyedPropertyLoad(prop);
3673 } 3728 }
3674 } 3729 }
3675 3730
3676 // We need a second deoptimization point after loading the value 3731 // We need a second deoptimization point after loading the value
3677 // in case evaluating the property load my have a side effect. 3732 // in case evaluating the property load my have a side effect.
3678 PrepareForBailout(expr->increment(), TOS_REG); 3733 if (assign_type == VARIABLE) {
3734 PrepareForBailout(expr->expression(), TOS_REG);
3735 } else {
3736 PrepareForBailout(expr->increment(), TOS_REG);
3737 }
3679 3738
3680 // Call ToNumber only if operand is not a smi. 3739 // Call ToNumber only if operand is not a smi.
3681 Label no_conversion; 3740 Label no_conversion;
3682 __ JumpIfSmi(r0, &no_conversion); 3741 __ JumpIfSmi(r0, &no_conversion);
3683 ToNumberStub convert_stub; 3742 ToNumberStub convert_stub;
3684 __ CallStub(&convert_stub); 3743 __ CallStub(&convert_stub);
3685 __ bind(&no_conversion); 3744 __ bind(&no_conversion);
3686 3745
3687 // Save result for postfix expressions. 3746 // Save result for postfix expressions.
3688 if (expr->is_postfix()) { 3747 if (expr->is_postfix()) {
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
4154 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 4213 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4155 __ add(pc, r1, Operand(masm_->CodeObject())); 4214 __ add(pc, r1, Operand(masm_->CodeObject()));
4156 } 4215 }
4157 4216
4158 4217
4159 #undef __ 4218 #undef __
4160 4219
4161 } } // namespace v8::internal 4220 } } // namespace v8::internal
4162 4221
4163 #endif // V8_TARGET_ARCH_ARM 4222 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/frames-arm.h ('k') | src/arm/lithium-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698