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

Side by Side Diff: src/ia32/full-codegen-ia32.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/ia32/frames-ia32.h ('k') | src/ia32/lithium-codegen-ia32.cc » ('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 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 __ mov(edx, Operand(esp, 0)); 1450 __ mov(edx, Operand(esp, 0));
1451 __ push(eax); 1451 __ push(eax);
1452 } else { 1452 } else {
1453 VisitForStackValue(property->obj()); 1453 VisitForStackValue(property->obj());
1454 VisitForStackValue(property->key()); 1454 VisitForStackValue(property->key());
1455 } 1455 }
1456 break; 1456 break;
1457 } 1457 }
1458 } 1458 }
1459 1459
1460 // For compound assignments we need another deoptimization point after the
1461 // variable/property load.
1462 if (expr->is_compound()) { 1460 if (expr->is_compound()) {
1463 { AccumulatorValueContext context(this); 1461 { AccumulatorValueContext context(this);
1464 switch (assign_type) { 1462 switch (assign_type) {
1465 case VARIABLE: 1463 case VARIABLE:
1466 EmitVariableLoad(expr->target()->AsVariableProxy()->var()); 1464 EmitVariableLoad(expr->target()->AsVariableProxy()->var());
1467 PrepareForBailout(expr->target(), TOS_REG);
1468 break; 1465 break;
1469 case NAMED_PROPERTY: 1466 case NAMED_PROPERTY:
1470 EmitNamedPropertyLoad(property); 1467 EmitNamedPropertyLoad(property);
1471 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1472 break; 1468 break;
1473 case KEYED_PROPERTY: 1469 case KEYED_PROPERTY:
1474 EmitKeyedPropertyLoad(property); 1470 EmitKeyedPropertyLoad(property);
1475 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1476 break; 1471 break;
1477 } 1472 }
1478 } 1473 }
1479 1474
1475 // For property compound assignments we need another deoptimization
1476 // point after the property load.
1477 if (property != NULL) {
1478 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1479 }
1480
1480 Token::Value op = expr->binary_op(); 1481 Token::Value op = expr->binary_op();
1481 __ push(eax); // Left operand goes on the stack. 1482 __ push(eax); // Left operand goes on the stack.
1482 VisitForAccumulatorValue(expr->value()); 1483 VisitForAccumulatorValue(expr->value());
1483 1484
1484 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1485 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1485 ? OVERWRITE_RIGHT 1486 ? OVERWRITE_RIGHT
1486 : NO_OVERWRITE; 1487 : NO_OVERWRITE;
1487 SetSourcePosition(expr->position() + 1); 1488 SetSourcePosition(expr->position() + 1);
1488 AccumulatorValueContext context(this); 1489 AccumulatorValueContext context(this);
1489 if (ShouldInlineSmiCase(op)) { 1490 if (ShouldInlineSmiCase(op)) {
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
2114 } 2115 }
2115 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2116 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2116 } else { 2117 } else {
2117 // Call to a keyed property. 2118 // Call to a keyed property.
2118 { PreservePositionScope scope(masm()->positions_recorder()); 2119 { PreservePositionScope scope(masm()->positions_recorder());
2119 VisitForStackValue(prop->obj()); 2120 VisitForStackValue(prop->obj());
2120 } 2121 }
2121 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2122 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2122 } 2123 }
2123 } else { 2124 } else {
2125 // Call to some other expression. If the expression is an anonymous
2126 // function literal not called in a loop, mark it as one that should
2127 // also use the full code generator.
2128 FunctionLiteral* lit = fun->AsFunctionLiteral();
2129 if (lit != NULL &&
2130 lit->name()->Equals(isolate()->heap()->empty_string()) &&
2131 loop_depth() == 0) {
2132 lit->set_try_full_codegen(true);
2133 }
2124 { PreservePositionScope scope(masm()->positions_recorder()); 2134 { PreservePositionScope scope(masm()->positions_recorder());
2125 VisitForStackValue(fun); 2135 VisitForStackValue(fun);
2126 } 2136 }
2127 // Load global receiver object. 2137 // Load global receiver object.
2128 __ mov(ebx, GlobalObjectOperand()); 2138 __ mov(ebx, GlobalObjectOperand());
2129 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2139 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2130 // Emit function call. 2140 // Emit function call.
2131 EmitCallWithStub(expr); 2141 EmitCallWithStub(expr);
2132 } 2142 }
2133 2143
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2295 2305
2296 VisitForAccumulatorValue(args->at(0)); 2306 VisitForAccumulatorValue(args->at(0));
2297 2307
2298 Label materialize_true, materialize_false; 2308 Label materialize_true, materialize_false;
2299 Label* if_true = NULL; 2309 Label* if_true = NULL;
2300 Label* if_false = NULL; 2310 Label* if_false = NULL;
2301 Label* fall_through = NULL; 2311 Label* fall_through = NULL;
2302 context()->PrepareTest(&materialize_true, &materialize_false, 2312 context()->PrepareTest(&materialize_true, &materialize_false,
2303 &if_true, &if_false, &fall_through); 2313 &if_true, &if_false, &fall_through);
2304 2314
2305 if (FLAG_debug_code) __ AbortIfSmi(eax); 2315 // TODO(3110205): Implement this.
2306 2316 // Currently unimplemented. Emit false, a safe choice.
2307 // Check whether this map has already been checked to be safe for default
2308 // valueOf.
2309 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
2310 __ test_b(FieldOperand(ebx, Map::kBitField2Offset),
2311 1 << Map::kStringWrapperSafeForDefaultValueOf);
2312 __ j(not_zero, if_true);
2313
2314 // Check for fast case object. Return false for slow case objects.
2315 __ mov(ecx, FieldOperand(eax, JSObject::kPropertiesOffset));
2316 __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
2317 __ cmp(ecx, FACTORY->hash_table_map());
2318 __ j(equal, if_false);
2319
2320 // Look for valueOf symbol in the descriptor array, and indicate false if
2321 // found. The type is not checked, so if it is a transition it is a false
2322 // negative.
2323 __ mov(ebx, FieldOperand(ebx, Map::kInstanceDescriptorsOffset));
2324 __ mov(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
2325 // ebx: descriptor array
2326 // ecx: length of descriptor array
2327 // Calculate the end of the descriptor array.
2328 STATIC_ASSERT(kSmiTag == 0);
2329 STATIC_ASSERT(kSmiTagSize == 1);
2330 STATIC_ASSERT(kPointerSize == 4);
2331 __ lea(ecx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize));
2332 // Calculate location of the first key name.
2333 __ add(Operand(ebx),
2334 Immediate(FixedArray::kHeaderSize +
2335 DescriptorArray::kFirstIndex * kPointerSize));
2336 // Loop through all the keys in the descriptor array. If one of these is the
2337 // symbol valueOf the result is false.
2338 Label entry, loop;
2339 __ jmp(&entry);
2340 __ bind(&loop);
2341 __ mov(edx, FieldOperand(ebx, 0));
2342 __ cmp(edx, FACTORY->value_of_symbol());
2343 __ j(equal, if_false);
2344 __ add(Operand(ebx), Immediate(kPointerSize));
2345 __ bind(&entry);
2346 __ cmp(ebx, Operand(ecx));
2347 __ j(not_equal, &loop);
2348
2349 // Reload map as register ebx was used as temporary above.
2350 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
2351
2352 // If a valueOf property is not found on the object check that it's
2353 // prototype is the un-modified String prototype. If not result is false.
2354 __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
2355 __ test(ecx, Immediate(kSmiTagMask));
2356 __ j(zero, if_false);
2357 __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
2358 __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
2359 __ mov(edx,
2360 FieldOperand(edx, GlobalObject::kGlobalContextOffset));
2361 __ cmp(ecx,
2362 ContextOperand(edx,
2363 Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
2364 __ j(not_equal, if_false);
2365 // Set the bit in the map to indicate that it has been checked safe for
2366 // default valueOf and set true result.
2367 __ or_(FieldOperand(ebx, Map::kBitField2Offset),
2368 Immediate(1 << Map::kStringWrapperSafeForDefaultValueOf));
2369 __ jmp(if_true);
2370
2371 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2317 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2318 __ jmp(if_false);
2372 context()->Plug(if_true, if_false); 2319 context()->Plug(if_true, if_false);
2373 } 2320 }
2374 2321
2375 2322
2376 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { 2323 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
2377 ASSERT(args->length() == 1); 2324 ASSERT(args->length() == 1);
2378 2325
2379 VisitForAccumulatorValue(args->at(0)); 2326 VisitForAccumulatorValue(args->at(0));
2380 2327
2381 Label materialize_true, materialize_false; 2328 Label materialize_true, materialize_false;
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
2617 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber); 2564 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber);
2618 __ jmp(&heapnumber_allocated); 2565 __ jmp(&heapnumber_allocated);
2619 2566
2620 __ bind(&slow_allocate_heapnumber); 2567 __ bind(&slow_allocate_heapnumber);
2621 // Allocate a heap number. 2568 // Allocate a heap number.
2622 __ CallRuntime(Runtime::kNumberAlloc, 0); 2569 __ CallRuntime(Runtime::kNumberAlloc, 0);
2623 __ mov(edi, eax); 2570 __ mov(edi, eax);
2624 2571
2625 __ bind(&heapnumber_allocated); 2572 __ bind(&heapnumber_allocated);
2626 2573
2627 __ PrepareCallCFunction(1, ebx); 2574 __ PrepareCallCFunction(0, ebx);
2628 __ mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address()));
2629 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 2575 __ CallCFunction(ExternalReference::random_uint32_function(isolate()),
2630 1); 2576 0);
2631 2577
2632 // Convert 32 random bits in eax to 0.(32 random bits) in a double 2578 // Convert 32 random bits in eax to 0.(32 random bits) in a double
2633 // by computing: 2579 // by computing:
2634 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 2580 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
2635 // This is implemented on both SSE2 and FPU. 2581 // This is implemented on both SSE2 and FPU.
2636 if (CpuFeatures::IsSupported(SSE2)) { 2582 if (isolate()->cpu_features()->IsSupported(SSE2)) {
2637 CpuFeatures::Scope fscope(SSE2); 2583 CpuFeatures::Scope fscope(SSE2);
2638 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. 2584 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
2639 __ movd(xmm1, Operand(ebx)); 2585 __ movd(xmm1, Operand(ebx));
2640 __ movd(xmm0, Operand(eax)); 2586 __ movd(xmm0, Operand(eax));
2641 __ cvtss2sd(xmm1, xmm1); 2587 __ cvtss2sd(xmm1, xmm1);
2642 __ pxor(xmm0, xmm1); 2588 __ pxor(xmm0, xmm1);
2643 __ subsd(xmm0, xmm1); 2589 __ subsd(xmm0, xmm1);
2644 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0); 2590 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0);
2645 } else { 2591 } else {
2646 // 0x4130000000000000 is 1.0 x 2^20 as a double. 2592 // 0x4130000000000000 is 1.0 x 2^20 as a double.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2701 context()->Plug(eax); 2647 context()->Plug(eax);
2702 } 2648 }
2703 2649
2704 2650
2705 void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) { 2651 void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) {
2706 // Load the arguments on the stack and call the runtime function. 2652 // Load the arguments on the stack and call the runtime function.
2707 ASSERT(args->length() == 2); 2653 ASSERT(args->length() == 2);
2708 VisitForStackValue(args->at(0)); 2654 VisitForStackValue(args->at(0));
2709 VisitForStackValue(args->at(1)); 2655 VisitForStackValue(args->at(1));
2710 2656
2711 if (CpuFeatures::IsSupported(SSE2)) { 2657 if (isolate()->cpu_features()->IsSupported(SSE2)) {
2712 MathPowStub stub; 2658 MathPowStub stub;
2713 __ CallStub(&stub); 2659 __ CallStub(&stub);
2714 } else { 2660 } else {
2715 __ CallRuntime(Runtime::kMath_pow, 2); 2661 __ CallRuntime(Runtime::kMath_pow, 2);
2716 } 2662 }
2717 context()->Plug(eax); 2663 context()->Plug(eax);
2718 } 2664 }
2719 2665
2720 2666
2721 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { 2667 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after
3665 VisitForStackValue(prop->obj()); 3611 VisitForStackValue(prop->obj());
3666 VisitForAccumulatorValue(prop->key()); 3612 VisitForAccumulatorValue(prop->key());
3667 __ mov(edx, Operand(esp, 0)); 3613 __ mov(edx, Operand(esp, 0));
3668 __ push(eax); 3614 __ push(eax);
3669 EmitKeyedPropertyLoad(prop); 3615 EmitKeyedPropertyLoad(prop);
3670 } 3616 }
3671 } 3617 }
3672 3618
3673 // We need a second deoptimization point after loading the value 3619 // We need a second deoptimization point after loading the value
3674 // in case evaluating the property load my have a side effect. 3620 // in case evaluating the property load my have a side effect.
3675 if (assign_type == VARIABLE) { 3621 PrepareForBailout(expr->increment(), TOS_REG);
3676 PrepareForBailout(expr->expression(), TOS_REG);
3677 } else {
3678 PrepareForBailout(expr->increment(), TOS_REG);
3679 }
3680 3622
3681 // Call ToNumber only if operand is not a smi. 3623 // Call ToNumber only if operand is not a smi.
3682 NearLabel no_conversion; 3624 NearLabel no_conversion;
3683 if (ShouldInlineSmiCase(expr->op())) { 3625 if (ShouldInlineSmiCase(expr->op())) {
3684 __ test(eax, Immediate(kSmiTagMask)); 3626 __ test(eax, Immediate(kSmiTagMask));
3685 __ j(zero, &no_conversion); 3627 __ j(zero, &no_conversion);
3686 } 3628 }
3687 ToNumberStub convert_stub; 3629 ToNumberStub convert_stub;
3688 __ CallStub(&convert_stub); 3630 __ CallStub(&convert_stub);
3689 __ bind(&no_conversion); 3631 __ bind(&no_conversion);
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
4188 // And return. 4130 // And return.
4189 __ ret(0); 4131 __ ret(0);
4190 } 4132 }
4191 4133
4192 4134
4193 #undef __ 4135 #undef __
4194 4136
4195 } } // namespace v8::internal 4137 } } // namespace v8::internal
4196 4138
4197 #endif // V8_TARGET_ARCH_IA32 4139 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/frames-ia32.h ('k') | src/ia32/lithium-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698