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

Side by Side Diff: src/ia32/full-codegen-ia32.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/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.
1460 if (expr->is_compound()) { 1462 if (expr->is_compound()) {
1461 { AccumulatorValueContext context(this); 1463 { AccumulatorValueContext context(this);
1462 switch (assign_type) { 1464 switch (assign_type) {
1463 case VARIABLE: 1465 case VARIABLE:
1464 EmitVariableLoad(expr->target()->AsVariableProxy()->var()); 1466 EmitVariableLoad(expr->target()->AsVariableProxy()->var());
1467 PrepareForBailout(expr->target(), TOS_REG);
1465 break; 1468 break;
1466 case NAMED_PROPERTY: 1469 case NAMED_PROPERTY:
1467 EmitNamedPropertyLoad(property); 1470 EmitNamedPropertyLoad(property);
1471 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1468 break; 1472 break;
1469 case KEYED_PROPERTY: 1473 case KEYED_PROPERTY:
1470 EmitKeyedPropertyLoad(property); 1474 EmitKeyedPropertyLoad(property);
1475 PrepareForBailoutForId(expr->CompoundLoadId(), TOS_REG);
1471 break; 1476 break;
1472 } 1477 }
1473 } 1478 }
1474 1479
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
1481 Token::Value op = expr->binary_op(); 1480 Token::Value op = expr->binary_op();
1482 __ push(eax); // Left operand goes on the stack. 1481 __ push(eax); // Left operand goes on the stack.
1483 VisitForAccumulatorValue(expr->value()); 1482 VisitForAccumulatorValue(expr->value());
1484 1483
1485 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1484 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1486 ? OVERWRITE_RIGHT 1485 ? OVERWRITE_RIGHT
1487 : NO_OVERWRITE; 1486 : NO_OVERWRITE;
1488 SetSourcePosition(expr->position() + 1); 1487 SetSourcePosition(expr->position() + 1);
1489 AccumulatorValueContext context(this); 1488 AccumulatorValueContext context(this);
1490 if (ShouldInlineSmiCase(op)) { 1489 if (ShouldInlineSmiCase(op)) {
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after
2115 } 2114 }
2116 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); 2115 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET);
2117 } else { 2116 } else {
2118 // Call to a keyed property. 2117 // Call to a keyed property.
2119 { PreservePositionScope scope(masm()->positions_recorder()); 2118 { PreservePositionScope scope(masm()->positions_recorder());
2120 VisitForStackValue(prop->obj()); 2119 VisitForStackValue(prop->obj());
2121 } 2120 }
2122 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET); 2121 EmitKeyedCallWithIC(expr, prop->key(), RelocInfo::CODE_TARGET);
2123 } 2122 }
2124 } else { 2123 } 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 }
2134 { PreservePositionScope scope(masm()->positions_recorder()); 2124 { PreservePositionScope scope(masm()->positions_recorder());
2135 VisitForStackValue(fun); 2125 VisitForStackValue(fun);
2136 } 2126 }
2137 // Load global receiver object. 2127 // Load global receiver object.
2138 __ mov(ebx, GlobalObjectOperand()); 2128 __ mov(ebx, GlobalObjectOperand());
2139 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); 2129 __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
2140 // Emit function call. 2130 // Emit function call.
2141 EmitCallWithStub(expr); 2131 EmitCallWithStub(expr);
2142 } 2132 }
2143 2133
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2305 2295
2306 VisitForAccumulatorValue(args->at(0)); 2296 VisitForAccumulatorValue(args->at(0));
2307 2297
2308 Label materialize_true, materialize_false; 2298 Label materialize_true, materialize_false;
2309 Label* if_true = NULL; 2299 Label* if_true = NULL;
2310 Label* if_false = NULL; 2300 Label* if_false = NULL;
2311 Label* fall_through = NULL; 2301 Label* fall_through = NULL;
2312 context()->PrepareTest(&materialize_true, &materialize_false, 2302 context()->PrepareTest(&materialize_true, &materialize_false,
2313 &if_true, &if_false, &fall_through); 2303 &if_true, &if_false, &fall_through);
2314 2304
2315 // TODO(3110205): Implement this. 2305 if (FLAG_debug_code) __ AbortIfSmi(eax);
2316 // Currently unimplemented. Emit false, a safe choice. 2306
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
2317 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2371 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2318 __ jmp(if_false);
2319 context()->Plug(if_true, if_false); 2372 context()->Plug(if_true, if_false);
2320 } 2373 }
2321 2374
2322 2375
2323 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) { 2376 void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
2324 ASSERT(args->length() == 1); 2377 ASSERT(args->length() == 1);
2325 2378
2326 VisitForAccumulatorValue(args->at(0)); 2379 VisitForAccumulatorValue(args->at(0));
2327 2380
2328 Label materialize_true, materialize_false; 2381 Label materialize_true, materialize_false;
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
2564 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber); 2617 __ AllocateHeapNumber(edi, ebx, ecx, &slow_allocate_heapnumber);
2565 __ jmp(&heapnumber_allocated); 2618 __ jmp(&heapnumber_allocated);
2566 2619
2567 __ bind(&slow_allocate_heapnumber); 2620 __ bind(&slow_allocate_heapnumber);
2568 // Allocate a heap number. 2621 // Allocate a heap number.
2569 __ CallRuntime(Runtime::kNumberAlloc, 0); 2622 __ CallRuntime(Runtime::kNumberAlloc, 0);
2570 __ mov(edi, eax); 2623 __ mov(edi, eax);
2571 2624
2572 __ bind(&heapnumber_allocated); 2625 __ bind(&heapnumber_allocated);
2573 2626
2574 __ PrepareCallCFunction(0, ebx); 2627 __ PrepareCallCFunction(1, ebx);
2628 __ mov(Operand(esp, 0), Immediate(ExternalReference::isolate_address()));
2575 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 2629 __ CallCFunction(ExternalReference::random_uint32_function(isolate()),
2576 0); 2630 1);
2577 2631
2578 // Convert 32 random bits in eax to 0.(32 random bits) in a double 2632 // Convert 32 random bits in eax to 0.(32 random bits) in a double
2579 // by computing: 2633 // by computing:
2580 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 2634 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
2581 // This is implemented on both SSE2 and FPU. 2635 // This is implemented on both SSE2 and FPU.
2582 if (isolate()->cpu_features()->IsSupported(SSE2)) { 2636 if (CpuFeatures::IsSupported(SSE2)) {
2583 CpuFeatures::Scope fscope(SSE2); 2637 CpuFeatures::Scope fscope(SSE2);
2584 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. 2638 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
2585 __ movd(xmm1, Operand(ebx)); 2639 __ movd(xmm1, Operand(ebx));
2586 __ movd(xmm0, Operand(eax)); 2640 __ movd(xmm0, Operand(eax));
2587 __ cvtss2sd(xmm1, xmm1); 2641 __ cvtss2sd(xmm1, xmm1);
2588 __ pxor(xmm0, xmm1); 2642 __ pxor(xmm0, xmm1);
2589 __ subsd(xmm0, xmm1); 2643 __ subsd(xmm0, xmm1);
2590 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0); 2644 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0);
2591 } else { 2645 } else {
2592 // 0x4130000000000000 is 1.0 x 2^20 as a double. 2646 // 0x4130000000000000 is 1.0 x 2^20 as a double.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2647 context()->Plug(eax); 2701 context()->Plug(eax);
2648 } 2702 }
2649 2703
2650 2704
2651 void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) { 2705 void FullCodeGenerator::EmitMathPow(ZoneList<Expression*>* args) {
2652 // Load the arguments on the stack and call the runtime function. 2706 // Load the arguments on the stack and call the runtime function.
2653 ASSERT(args->length() == 2); 2707 ASSERT(args->length() == 2);
2654 VisitForStackValue(args->at(0)); 2708 VisitForStackValue(args->at(0));
2655 VisitForStackValue(args->at(1)); 2709 VisitForStackValue(args->at(1));
2656 2710
2657 if (isolate()->cpu_features()->IsSupported(SSE2)) { 2711 if (CpuFeatures::IsSupported(SSE2)) {
2658 MathPowStub stub; 2712 MathPowStub stub;
2659 __ CallStub(&stub); 2713 __ CallStub(&stub);
2660 } else { 2714 } else {
2661 __ CallRuntime(Runtime::kMath_pow, 2); 2715 __ CallRuntime(Runtime::kMath_pow, 2);
2662 } 2716 }
2663 context()->Plug(eax); 2717 context()->Plug(eax);
2664 } 2718 }
2665 2719
2666 2720
2667 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { 2721 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after
3611 VisitForStackValue(prop->obj()); 3665 VisitForStackValue(prop->obj());
3612 VisitForAccumulatorValue(prop->key()); 3666 VisitForAccumulatorValue(prop->key());
3613 __ mov(edx, Operand(esp, 0)); 3667 __ mov(edx, Operand(esp, 0));
3614 __ push(eax); 3668 __ push(eax);
3615 EmitKeyedPropertyLoad(prop); 3669 EmitKeyedPropertyLoad(prop);
3616 } 3670 }
3617 } 3671 }
3618 3672
3619 // We need a second deoptimization point after loading the value 3673 // We need a second deoptimization point after loading the value
3620 // in case evaluating the property load my have a side effect. 3674 // in case evaluating the property load my have a side effect.
3621 PrepareForBailout(expr->increment(), TOS_REG); 3675 if (assign_type == VARIABLE) {
3676 PrepareForBailout(expr->expression(), TOS_REG);
3677 } else {
3678 PrepareForBailout(expr->increment(), TOS_REG);
3679 }
3622 3680
3623 // Call ToNumber only if operand is not a smi. 3681 // Call ToNumber only if operand is not a smi.
3624 NearLabel no_conversion; 3682 NearLabel no_conversion;
3625 if (ShouldInlineSmiCase(expr->op())) { 3683 if (ShouldInlineSmiCase(expr->op())) {
3626 __ test(eax, Immediate(kSmiTagMask)); 3684 __ test(eax, Immediate(kSmiTagMask));
3627 __ j(zero, &no_conversion); 3685 __ j(zero, &no_conversion);
3628 } 3686 }
3629 ToNumberStub convert_stub; 3687 ToNumberStub convert_stub;
3630 __ CallStub(&convert_stub); 3688 __ CallStub(&convert_stub);
3631 __ bind(&no_conversion); 3689 __ bind(&no_conversion);
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
4130 // And return. 4188 // And return.
4131 __ ret(0); 4189 __ ret(0);
4132 } 4190 }
4133 4191
4134 4192
4135 #undef __ 4193 #undef __
4136 4194
4137 } } // namespace v8::internal 4195 } } // namespace v8::internal
4138 4196
4139 #endif // V8_TARGET_ARCH_IA32 4197 #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