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

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

Issue 6794050: Revert "[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 (CpuFeatures::IsSupported(VFP3)) { 559 if (Isolate::Current()->cpu_features()->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.
1526 if (expr->is_compound()) { 1524 if (expr->is_compound()) {
1527 { AccumulatorValueContext context(this); 1525 { AccumulatorValueContext context(this);
1528 switch (assign_type) { 1526 switch (assign_type) {
1529 case VARIABLE: 1527 case VARIABLE:
1530 EmitVariableLoad(expr->target()->AsVariableProxy()->var()); 1528 EmitVariableLoad(expr->target()->AsVariableProxy()->var());
1531 PrepareForBailout(expr->target(), TOS_REG);
1532 break; 1529 break;
1533 case NAMED_PROPERTY: 1530 case NAMED_PROPERTY:
1534 EmitNamedPropertyLoad(property); 1531 EmitNamedPropertyLoad(property);
1535 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1536 break; 1532 break;
1537 case KEYED_PROPERTY: 1533 case KEYED_PROPERTY:
1538 EmitKeyedPropertyLoad(property); 1534 EmitKeyedPropertyLoad(property);
1539 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1540 break; 1535 break;
1541 } 1536 }
1542 } 1537 }
1543 1538
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
1544 Token::Value op = expr->binary_op(); 1545 Token::Value op = expr->binary_op();
1545 __ push(r0); // Left operand goes on the stack. 1546 __ push(r0); // Left operand goes on the stack.
1546 VisitForAccumulatorValue(expr->value()); 1547 VisitForAccumulatorValue(expr->value());
1547 1548
1548 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1549 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1549 ? OVERWRITE_RIGHT 1550 ? OVERWRITE_RIGHT
1550 : NO_OVERWRITE; 1551 : NO_OVERWRITE;
1551 SetSourcePosition(expr->position() + 1); 1552 SetSourcePosition(expr->position() + 1);
1552 AccumulatorValueContext context(this); 1553 AccumulatorValueContext context(this);
1553 if (ShouldInlineSmiCase(op)) { 1554 if (ShouldInlineSmiCase(op)) {
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
2205 } 2206 }
2206 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2207 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2207 } else { 2208 } else {
2208 // Call to a keyed property. 2209 // Call to a keyed property.
2209 { PreservePositionScope scope(masm()->positions_recorder()); 2210 { PreservePositionScope scope(masm()->positions_recorder());
2210 VisitForStackValue(prop->obj()); 2211 VisitForStackValue(prop->obj());
2211 } 2212 }
2212 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2213 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2213 } 2214 }
2214 } else { 2215 } 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
2215 { PreservePositionScope scope(masm()->positions_recorder()); 2226 { PreservePositionScope scope(masm()->positions_recorder());
2216 VisitForStackValue(fun); 2227 VisitForStackValue(fun);
2217 } 2228 }
2218 // Load global receiver object. 2229 // Load global receiver object.
2219 __ ldr(r1, GlobalObjectOperand()); 2230 __ ldr(r1, GlobalObjectOperand());
2220 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); 2231 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
2221 __ push(r1); 2232 __ push(r1);
2222 // Emit function call. 2233 // Emit function call.
2223 EmitCallWithStub(expr); 2234 EmitCallWithStub(expr);
2224 } 2235 }
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2386 2397
2387 VisitForAccumulatorValue(args->at(0)); 2398 VisitForAccumulatorValue(args->at(0));
2388 2399
2389 Label materialize_true, materialize_false; 2400 Label materialize_true, materialize_false;
2390 Label* if_true = NULL; 2401 Label* if_true = NULL;
2391 Label* if_false = NULL; 2402 Label* if_false = NULL;
2392 Label* fall_through = NULL; 2403 Label* fall_through = NULL;
2393 context()->PrepareTest(&materialize_true, &materialize_false, 2404 context()->PrepareTest(&materialize_true, &materialize_false,
2394 &if_true, &if_false, &fall_through); 2405 &if_true, &if_false, &fall_through);
2395 2406
2396 if (FLAG_debug_code) __ AbortIfSmi(r0); 2407 // Just indicate false, as %_IsStringWrapperSafeForDefaultValueOf() is only
2397 2408 // used in a few functions in runtime.js which should not normally be hit by
2398 __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); 2409 // this compiler.
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
2464 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2410 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2411 __ jmp(if_false);
2465 context()->Plug(if_true, if_false); 2412 context()->Plug(if_true, if_false);
2466 } 2413 }
2467 2414
2468 2415
2469 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { 2416 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
2470 ASSERT(args->length() == 1); 2417 ASSERT(args->length() == 1);
2471 2418
2472 VisitForAccumulatorValue(args->at(0)); 2419 VisitForAccumulatorValue(args->at(0));
2473 2420
2474 Label materialize_true, materialize_false; 2421 Label materialize_true, materialize_false;
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
2709 __ bind(&slow_allocate_heapnumber); 2656 __ bind(&slow_allocate_heapnumber);
2710 // Allocate a heap number. 2657 // Allocate a heap number.
2711 __ CallRuntime(Runtime::kNumberAlloc, 0); 2658 __ CallRuntime(Runtime::kNumberAlloc, 0);
2712 __ mov(r4, Operand(r0)); 2659 __ mov(r4, Operand(r0));
2713 2660
2714 __ bind(&heapnumber_allocated); 2661 __ bind(&heapnumber_allocated);
2715 2662
2716 // Convert 32 random bits in r0 to 0.(32 random bits) in a double 2663 // Convert 32 random bits in r0 to 0.(32 random bits) in a double
2717 // by computing: 2664 // by computing:
2718 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 2665 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
2719 if (CpuFeatures::IsSupported(VFP3)) { 2666 if (isolate()->cpu_features()->IsSupported(VFP3)) {
2720 __ PrepareCallCFunction(1, r0); 2667 __ PrepareCallCFunction(0, r1);
2721 __ mov(r0, Operand(ExternalReference::isolate_address())); 2668 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 0);
2722 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
2723 2669
2724 CpuFeatures::Scope scope(VFP3); 2670 CpuFeatures::Scope scope(VFP3);
2725 // 0x41300000 is the top half of 1.0 x 2^20 as a double. 2671 // 0x41300000 is the top half of 1.0 x 2^20 as a double.
2726 // Create this constant using mov/orr to avoid PC relative load. 2672 // Create this constant using mov/orr to avoid PC relative load.
2727 __ mov(r1, Operand(0x41000000)); 2673 __ mov(r1, Operand(0x41000000));
2728 __ orr(r1, r1, Operand(0x300000)); 2674 __ orr(r1, r1, Operand(0x300000));
2729 // Move 0x41300000xxxxxxxx (x = random bits) to VFP. 2675 // Move 0x41300000xxxxxxxx (x = random bits) to VFP.
2730 __ vmov(d7, r0, r1); 2676 __ vmov(d7, r0, r1);
2731 // Move 0x4130000000000000 to VFP. 2677 // Move 0x4130000000000000 to VFP.
2732 __ mov(r0, Operand(0, RelocInfo::NONE)); 2678 __ mov(r0, Operand(0, RelocInfo::NONE));
2733 __ vmov(d8, r0, r1); 2679 __ vmov(d8, r0, r1);
2734 // Subtract and store the result in the heap number. 2680 // Subtract and store the result in the heap number.
2735 __ vsub(d7, d7, d8); 2681 __ vsub(d7, d7, d8);
2736 __ sub(r0, r4, Operand(kHeapObjectTag)); 2682 __ sub(r0, r4, Operand(kHeapObjectTag));
2737 __ vstr(d7, r0, HeapNumber::kValueOffset); 2683 __ vstr(d7, r0, HeapNumber::kValueOffset);
2738 __ mov(r0, r4); 2684 __ mov(r0, r4);
2739 } else { 2685 } else {
2740 __ PrepareCallCFunction(2, r0);
2741 __ mov(r0, Operand(r4)); 2686 __ mov(r0, Operand(r4));
2742 __ mov(r1, Operand(ExternalReference::isolate_address())); 2687 __ PrepareCallCFunction(1, r1);
2743 __ CallCFunction( 2688 __ CallCFunction(
2744 ExternalReference::fill_heap_number_with_random_function(isolate()), 2); 2689 ExternalReference::fill_heap_number_with_random_function(isolate()), 1);
2745 } 2690 }
2746 2691
2747 context()->Plug(r0); 2692 context()->Plug(r0);
2748 } 2693 }
2749 2694
2750 2695
2751 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) { 2696 void FullCodeGenerator::EmitSubString(ZoneList<Expression*>* args) {
2752 // Load the arguments on the stack and call the stub. 2697 // Load the arguments on the stack and call the stub.
2753 SubStringStub stub; 2698 SubStringStub stub;
2754 ASSERT(args->length() == 3); 2699 ASSERT(args->length() == 3);
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
3723 VisitForStackValue(prop->obj()); 3668 VisitForStackValue(prop->obj());
3724 VisitForAccumulatorValue(prop->key()); 3669 VisitForAccumulatorValue(prop->key());
3725 __ ldr(r1, MemOperand(sp, 0)); 3670 __ ldr(r1, MemOperand(sp, 0));
3726 __ push(r0); 3671 __ push(r0);
3727 EmitKeyedPropertyLoad(prop); 3672 EmitKeyedPropertyLoad(prop);
3728 } 3673 }
3729 } 3674 }
3730 3675
3731 // We need a second deoptimization point after loading the value 3676 // We need a second deoptimization point after loading the value
3732 // in case evaluating the property load my have a side effect. 3677 // in case evaluating the property load my have a side effect.
3733 if (assign_type == VARIABLE) { 3678 PrepareForBailout(expr->increment(), TOS_REG);
3734 PrepareForBailout(expr->expression(), TOS_REG);
3735 } else {
3736 PrepareForBailout(expr->increment(), TOS_REG);
3737 }
3738 3679
3739 // Call ToNumber only if operand is not a smi. 3680 // Call ToNumber only if operand is not a smi.
3740 Label no_conversion; 3681 Label no_conversion;
3741 __ JumpIfSmi(r0, &no_conversion); 3682 __ JumpIfSmi(r0, &no_conversion);
3742 ToNumberStub convert_stub; 3683 ToNumberStub convert_stub;
3743 __ CallStub(&convert_stub); 3684 __ CallStub(&convert_stub);
3744 __ bind(&no_conversion); 3685 __ bind(&no_conversion);
3745 3686
3746 // Save result for postfix expressions. 3687 // Save result for postfix expressions.
3747 if (expr->is_postfix()) { 3688 if (expr->is_postfix()) {
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
4213 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. 4154 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value.
4214 __ add(pc, r1, Operand(masm_->CodeObject())); 4155 __ add(pc, r1, Operand(masm_->CodeObject()));
4215 } 4156 }
4216 4157
4217 4158
4218 #undef __ 4159 #undef __
4219 4160
4220 } } // namespace v8::internal 4161 } } // namespace v8::internal
4221 4162
4222 #endif // V8_TARGET_ARCH_ARM 4163 #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