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

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

Issue 7191007: Cleanup: use JumpIf[Not]Smi() whenever we can (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: introduced new macro Created 9 years, 6 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/code-stubs-ia32.cc ('k') | src/ia32/ic-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 856 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 // ignore null and undefined in contrast to the specification; see 867 // ignore null and undefined in contrast to the specification; see
868 // ECMA-262 section 12.6.4. 868 // ECMA-262 section 12.6.4.
869 VisitForAccumulatorValue(stmt->enumerable()); 869 VisitForAccumulatorValue(stmt->enumerable());
870 __ cmp(eax, isolate()->factory()->undefined_value()); 870 __ cmp(eax, isolate()->factory()->undefined_value());
871 __ j(equal, &exit); 871 __ j(equal, &exit);
872 __ cmp(eax, isolate()->factory()->null_value()); 872 __ cmp(eax, isolate()->factory()->null_value());
873 __ j(equal, &exit); 873 __ j(equal, &exit);
874 874
875 // Convert the object to a JS object. 875 // Convert the object to a JS object.
876 Label convert, done_convert; 876 Label convert, done_convert;
877 __ test(eax, Immediate(kSmiTagMask)); 877 __ JumpIfSmi(eax, &convert, Label::kNear);
878 __ j(zero, &convert, Label::kNear);
879 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 878 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
880 __ j(above_equal, &done_convert, Label::kNear); 879 __ j(above_equal, &done_convert, Label::kNear);
881 __ bind(&convert); 880 __ bind(&convert);
882 __ push(eax); 881 __ push(eax);
883 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 882 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
884 __ bind(&done_convert); 883 __ bind(&done_convert);
885 __ push(eax); 884 __ push(eax);
886 885
887 // Check cache validity in generated code. This is a fast case for 886 // Check cache validity in generated code. This is a fast case for
888 // the JSObject::IsSimpleEnum cache validity checks. If we cannot 887 // the JSObject::IsSimpleEnum cache validity checks. If we cannot
(...skipping 13 matching lines...) Expand all
902 // check for an enum cache. Leave the map in ebx for the subsequent 901 // check for an enum cache. Leave the map in ebx for the subsequent
903 // prototype load. 902 // prototype load.
904 __ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset)); 903 __ mov(ebx, FieldOperand(ecx, HeapObject::kMapOffset));
905 __ mov(edx, FieldOperand(ebx, Map::kInstanceDescriptorsOrBitField3Offset)); 904 __ mov(edx, FieldOperand(ebx, Map::kInstanceDescriptorsOrBitField3Offset));
906 __ JumpIfSmi(edx, &call_runtime); 905 __ JumpIfSmi(edx, &call_runtime);
907 906
908 // Check that there is an enum cache in the non-empty instance 907 // Check that there is an enum cache in the non-empty instance
909 // descriptors (edx). This is the case if the next enumeration 908 // descriptors (edx). This is the case if the next enumeration
910 // index field does not contain a smi. 909 // index field does not contain a smi.
911 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset)); 910 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumerationIndexOffset));
912 __ test(edx, Immediate(kSmiTagMask)); 911 __ JumpIfSmi(edx, &call_runtime);
913 __ j(zero, &call_runtime);
914 912
915 // For all objects but the receiver, check that the cache is empty. 913 // For all objects but the receiver, check that the cache is empty.
916 Label check_prototype; 914 Label check_prototype;
917 __ cmp(ecx, Operand(eax)); 915 __ cmp(ecx, Operand(eax));
918 __ j(equal, &check_prototype, Label::kNear); 916 __ j(equal, &check_prototype, Label::kNear);
919 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 917 __ mov(edx, FieldOperand(edx, DescriptorArray::kEnumCacheBridgeCacheOffset));
920 __ cmp(edx, isolate()->factory()->empty_fixed_array()); 918 __ cmp(edx, isolate()->factory()->empty_fixed_array());
921 __ j(not_equal, &call_runtime); 919 __ j(not_equal, &call_runtime);
922 920
923 // Load the prototype from the map and loop if non-null. 921 // Load the prototype from the map and loop if non-null.
(...skipping 1455 matching lines...) Expand 10 before | Expand all | Expand 10 after
2379 2377
2380 VisitForAccumulatorValue(args->at(0)); 2378 VisitForAccumulatorValue(args->at(0));
2381 2379
2382 Label materialize_true, materialize_false; 2380 Label materialize_true, materialize_false;
2383 Label* if_true = NULL; 2381 Label* if_true = NULL;
2384 Label* if_false = NULL; 2382 Label* if_false = NULL;
2385 Label* fall_through = NULL; 2383 Label* fall_through = NULL;
2386 context()->PrepareTest(&materialize_true, &materialize_false, 2384 context()->PrepareTest(&materialize_true, &materialize_false,
2387 &if_true, &if_false, &fall_through); 2385 &if_true, &if_false, &fall_through);
2388 2386
2389 __ test(eax, Immediate(kSmiTagMask)); 2387 __ JumpIfSmi(eax, if_false);
2390 __ j(zero, if_false);
2391 __ cmp(eax, isolate()->factory()->null_value()); 2388 __ cmp(eax, isolate()->factory()->null_value());
2392 __ j(equal, if_true); 2389 __ j(equal, if_true);
2393 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 2390 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
2394 // Undetectable objects behave like undefined when tested with typeof. 2391 // Undetectable objects behave like undefined when tested with typeof.
2395 __ movzx_b(ecx, FieldOperand(ebx, Map::kBitFieldOffset)); 2392 __ movzx_b(ecx, FieldOperand(ebx, Map::kBitFieldOffset));
2396 __ test(ecx, Immediate(1 << Map::kIsUndetectable)); 2393 __ test(ecx, Immediate(1 << Map::kIsUndetectable));
2397 __ j(not_zero, if_false); 2394 __ j(not_zero, if_false);
2398 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 2395 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset));
2399 __ cmp(ecx, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE); 2396 __ cmp(ecx, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
2400 __ j(below, if_false); 2397 __ j(below, if_false);
(...skipping 10 matching lines...) Expand all
2411 2408
2412 VisitForAccumulatorValue(args->at(0)); 2409 VisitForAccumulatorValue(args->at(0));
2413 2410
2414 Label materialize_true, materialize_false; 2411 Label materialize_true, materialize_false;
2415 Label* if_true = NULL; 2412 Label* if_true = NULL;
2416 Label* if_false = NULL; 2413 Label* if_false = NULL;
2417 Label* fall_through = NULL; 2414 Label* fall_through = NULL;
2418 context()->PrepareTest(&materialize_true, &materialize_false, 2415 context()->PrepareTest(&materialize_true, &materialize_false,
2419 &if_true, &if_false, &fall_through); 2416 &if_true, &if_false, &fall_through);
2420 2417
2421 __ test(eax, Immediate(kSmiTagMask)); 2418 __ JumpIfSmi(eax, if_false);
2422 __ j(equal, if_false);
2423 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ebx); 2419 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ebx);
2424 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2420 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2425 Split(above_equal, if_true, if_false, fall_through); 2421 Split(above_equal, if_true, if_false, fall_through);
2426 2422
2427 context()->Plug(if_true, if_false); 2423 context()->Plug(if_true, if_false);
2428 } 2424 }
2429 2425
2430 2426
2431 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) { 2427 void FullCodeGenerator::EmitIsUndetectableObject(ZoneList<Expression*>* args) {
2432 ASSERT(args->length() == 1); 2428 ASSERT(args->length() == 1);
2433 2429
2434 VisitForAccumulatorValue(args->at(0)); 2430 VisitForAccumulatorValue(args->at(0));
2435 2431
2436 Label materialize_true, materialize_false; 2432 Label materialize_true, materialize_false;
2437 Label* if_true = NULL; 2433 Label* if_true = NULL;
2438 Label* if_false = NULL; 2434 Label* if_false = NULL;
2439 Label* fall_through = NULL; 2435 Label* fall_through = NULL;
2440 context()->PrepareTest(&materialize_true, &materialize_false, 2436 context()->PrepareTest(&materialize_true, &materialize_false,
2441 &if_true, &if_false, &fall_through); 2437 &if_true, &if_false, &fall_through);
2442 2438
2443 __ test(eax, Immediate(kSmiTagMask)); 2439 __ JumpIfSmi(eax, if_false);
2444 __ j(zero, if_false);
2445 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 2440 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
2446 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset)); 2441 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
2447 __ test(ebx, Immediate(1 << Map::kIsUndetectable)); 2442 __ test(ebx, Immediate(1 << Map::kIsUndetectable));
2448 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2443 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2449 Split(not_zero, if_true, if_false, fall_through); 2444 Split(not_zero, if_true, if_false, fall_through);
2450 2445
2451 context()->Plug(if_true, if_false); 2446 context()->Plug(if_true, if_false);
2452 } 2447 }
2453 2448
2454 2449
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2508 __ bind(&entry); 2503 __ bind(&entry);
2509 __ cmp(ebx, Operand(ecx)); 2504 __ cmp(ebx, Operand(ecx));
2510 __ j(not_equal, &loop); 2505 __ j(not_equal, &loop);
2511 2506
2512 // Reload map as register ebx was used as temporary above. 2507 // Reload map as register ebx was used as temporary above.
2513 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 2508 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
2514 2509
2515 // If a valueOf property is not found on the object check that it's 2510 // If a valueOf property is not found on the object check that it's
2516 // prototype is the un-modified String prototype. If not result is false. 2511 // prototype is the un-modified String prototype. If not result is false.
2517 __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset)); 2512 __ mov(ecx, FieldOperand(ebx, Map::kPrototypeOffset));
2518 __ test(ecx, Immediate(kSmiTagMask)); 2513 __ JumpIfSmi(ecx, if_false);
2519 __ j(zero, if_false);
2520 __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset)); 2514 __ mov(ecx, FieldOperand(ecx, HeapObject::kMapOffset));
2521 __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); 2515 __ mov(edx, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)));
2522 __ mov(edx, 2516 __ mov(edx,
2523 FieldOperand(edx, GlobalObject::kGlobalContextOffset)); 2517 FieldOperand(edx, GlobalObject::kGlobalContextOffset));
2524 __ cmp(ecx, 2518 __ cmp(ecx,
2525 ContextOperand(edx, 2519 ContextOperand(edx,
2526 Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX)); 2520 Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
2527 __ j(not_equal, if_false); 2521 __ j(not_equal, if_false);
2528 // Set the bit in the map to indicate that it has been checked safe for 2522 // Set the bit in the map to indicate that it has been checked safe for
2529 // default valueOf and set true result. 2523 // default valueOf and set true result.
(...skipping 11 matching lines...) Expand all
2541 2535
2542 VisitForAccumulatorValue(args->at(0)); 2536 VisitForAccumulatorValue(args->at(0));
2543 2537
2544 Label materialize_true, materialize_false; 2538 Label materialize_true, materialize_false;
2545 Label* if_true = NULL; 2539 Label* if_true = NULL;
2546 Label* if_false = NULL; 2540 Label* if_false = NULL;
2547 Label* fall_through = NULL; 2541 Label* fall_through = NULL;
2548 context()->PrepareTest(&materialize_true, &materialize_false, 2542 context()->PrepareTest(&materialize_true, &materialize_false,
2549 &if_true, &if_false, &fall_through); 2543 &if_true, &if_false, &fall_through);
2550 2544
2551 __ test(eax, Immediate(kSmiTagMask)); 2545 __ JumpIfSmi(eax, if_false);
2552 __ j(zero, if_false);
2553 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); 2546 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
2554 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2547 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2555 Split(equal, if_true, if_false, fall_through); 2548 Split(equal, if_true, if_false, fall_through);
2556 2549
2557 context()->Plug(if_true, if_false); 2550 context()->Plug(if_true, if_false);
2558 } 2551 }
2559 2552
2560 2553
2561 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) { 2554 void FullCodeGenerator::EmitIsArray(ZoneList<Expression*>* args) {
2562 ASSERT(args->length() == 1); 2555 ASSERT(args->length() == 1);
2563 2556
2564 VisitForAccumulatorValue(args->at(0)); 2557 VisitForAccumulatorValue(args->at(0));
2565 2558
2566 Label materialize_true, materialize_false; 2559 Label materialize_true, materialize_false;
2567 Label* if_true = NULL; 2560 Label* if_true = NULL;
2568 Label* if_false = NULL; 2561 Label* if_false = NULL;
2569 Label* fall_through = NULL; 2562 Label* fall_through = NULL;
2570 context()->PrepareTest(&materialize_true, &materialize_false, 2563 context()->PrepareTest(&materialize_true, &materialize_false,
2571 &if_true, &if_false, &fall_through); 2564 &if_true, &if_false, &fall_through);
2572 2565
2573 __ test(eax, Immediate(kSmiTagMask)); 2566 __ JumpIfSmi(eax, if_false);
2574 __ j(equal, if_false);
2575 __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx); 2567 __ CmpObjectType(eax, JS_ARRAY_TYPE, ebx);
2576 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2568 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2577 Split(equal, if_true, if_false, fall_through); 2569 Split(equal, if_true, if_false, fall_through);
2578 2570
2579 context()->Plug(if_true, if_false); 2571 context()->Plug(if_true, if_false);
2580 } 2572 }
2581 2573
2582 2574
2583 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) { 2575 void FullCodeGenerator::EmitIsRegExp(ZoneList<Expression*>* args) {
2584 ASSERT(args->length() == 1); 2576 ASSERT(args->length() == 1);
2585 2577
2586 VisitForAccumulatorValue(args->at(0)); 2578 VisitForAccumulatorValue(args->at(0));
2587 2579
2588 Label materialize_true, materialize_false; 2580 Label materialize_true, materialize_false;
2589 Label* if_true = NULL; 2581 Label* if_true = NULL;
2590 Label* if_false = NULL; 2582 Label* if_false = NULL;
2591 Label* fall_through = NULL; 2583 Label* fall_through = NULL;
2592 context()->PrepareTest(&materialize_true, &materialize_false, 2584 context()->PrepareTest(&materialize_true, &materialize_false,
2593 &if_true, &if_false, &fall_through); 2585 &if_true, &if_false, &fall_through);
2594 2586
2595 __ test(eax, Immediate(kSmiTagMask)); 2587 __ JumpIfSmi(eax, if_false);
2596 __ j(equal, if_false);
2597 __ CmpObjectType(eax, JS_REGEXP_TYPE, ebx); 2588 __ CmpObjectType(eax, JS_REGEXP_TYPE, ebx);
2598 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 2589 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
2599 Split(equal, if_true, if_false, fall_through); 2590 Split(equal, if_true, if_false, fall_through);
2600 2591
2601 context()->Plug(if_true, if_false); 2592 context()->Plug(if_true, if_false);
2602 } 2593 }
2603 2594
2604 2595
2605 2596
2606 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) { 2597 void FullCodeGenerator::EmitIsConstructCall(ZoneList<Expression*>* args) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2694 } 2685 }
2695 2686
2696 2687
2697 void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) { 2688 void FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
2698 ASSERT(args->length() == 1); 2689 ASSERT(args->length() == 1);
2699 Label done, null, function, non_function_constructor; 2690 Label done, null, function, non_function_constructor;
2700 2691
2701 VisitForAccumulatorValue(args->at(0)); 2692 VisitForAccumulatorValue(args->at(0));
2702 2693
2703 // If the object is a smi, we return null. 2694 // If the object is a smi, we return null.
2704 __ test(eax, Immediate(kSmiTagMask)); 2695 __ JumpIfSmi(eax, &null);
2705 __ j(zero, &null);
2706 2696
2707 // Check that the object is a JS object but take special care of JS 2697 // Check that the object is a JS object but take special care of JS
2708 // functions to make sure they have 'Function' as their class. 2698 // functions to make sure they have 'Function' as their class.
2709 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, eax); 2699 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, eax);
2710 // Map is now in eax. 2700 // Map is now in eax.
2711 __ j(below, &null); 2701 __ j(below, &null);
2712 2702
2713 // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and 2703 // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type, and
2714 // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after 2704 // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
2715 // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter. 2705 // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the latter.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
2848 } 2838 }
2849 2839
2850 2840
2851 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) { 2841 void FullCodeGenerator::EmitValueOf(ZoneList<Expression*>* args) {
2852 ASSERT(args->length() == 1); 2842 ASSERT(args->length() == 1);
2853 2843
2854 VisitForAccumulatorValue(args->at(0)); // Load the object. 2844 VisitForAccumulatorValue(args->at(0)); // Load the object.
2855 2845
2856 Label done; 2846 Label done;
2857 // If the object is a smi return the object. 2847 // If the object is a smi return the object.
2858 __ test(eax, Immediate(kSmiTagMask)); 2848 __ JumpIfSmi(eax, &done, Label::kNear);
2859 __ j(zero, &done, Label::kNear);
2860 // If the object is not a value type, return the object. 2849 // If the object is not a value type, return the object.
2861 __ CmpObjectType(eax, JS_VALUE_TYPE, ebx); 2850 __ CmpObjectType(eax, JS_VALUE_TYPE, ebx);
2862 __ j(not_equal, &done, Label::kNear); 2851 __ j(not_equal, &done, Label::kNear);
2863 __ mov(eax, FieldOperand(eax, JSValue::kValueOffset)); 2852 __ mov(eax, FieldOperand(eax, JSValue::kValueOffset));
2864 2853
2865 __ bind(&done); 2854 __ bind(&done);
2866 context()->Plug(eax); 2855 context()->Plug(eax);
2867 } 2856 }
2868 2857
2869 2858
(...skipping 15 matching lines...) Expand all
2885 2874
2886 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) { 2875 void FullCodeGenerator::EmitSetValueOf(ZoneList<Expression*>* args) {
2887 ASSERT(args->length() == 2); 2876 ASSERT(args->length() == 2);
2888 2877
2889 VisitForStackValue(args->at(0)); // Load the object. 2878 VisitForStackValue(args->at(0)); // Load the object.
2890 VisitForAccumulatorValue(args->at(1)); // Load the value. 2879 VisitForAccumulatorValue(args->at(1)); // Load the value.
2891 __ pop(ebx); // eax = value. ebx = object. 2880 __ pop(ebx); // eax = value. ebx = object.
2892 2881
2893 Label done; 2882 Label done;
2894 // If the object is a smi, return the value. 2883 // If the object is a smi, return the value.
2895 __ test(ebx, Immediate(kSmiTagMask)); 2884 __ JumpIfSmi(ebx, &done, Label::kNear);
2896 __ j(zero, &done, Label::kNear);
2897 2885
2898 // If the object is not a value type, return the value. 2886 // If the object is not a value type, return the value.
2899 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx); 2887 __ CmpObjectType(ebx, JS_VALUE_TYPE, ecx);
2900 __ j(not_equal, &done, Label::kNear); 2888 __ j(not_equal, &done, Label::kNear);
2901 2889
2902 // Store the value. 2890 // Store the value.
2903 __ mov(FieldOperand(ebx, JSValue::kValueOffset), eax); 2891 __ mov(FieldOperand(ebx, JSValue::kValueOffset), eax);
2904 // Update the write barrier. Save the value as it will be 2892 // Update the write barrier. Save the value as it will be
2905 // overwritten by the write barrier code and is needed afterward. 2893 // overwritten by the write barrier code and is needed afterward.
2906 __ mov(edx, eax); 2894 __ mov(edx, eax);
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
3160 __ mov(elements, FieldOperand(object, JSObject::kElementsOffset)); 3148 __ mov(elements, FieldOperand(object, JSObject::kElementsOffset));
3161 __ cmp(FieldOperand(elements, HeapObject::kMapOffset), 3149 __ cmp(FieldOperand(elements, HeapObject::kMapOffset),
3162 Immediate(isolate()->factory()->fixed_array_map())); 3150 Immediate(isolate()->factory()->fixed_array_map()));
3163 __ j(not_equal, &slow_case); 3151 __ j(not_equal, &slow_case);
3164 3152
3165 // Check that both indices are smis. 3153 // Check that both indices are smis.
3166 __ mov(index_1, Operand(esp, 1 * kPointerSize)); 3154 __ mov(index_1, Operand(esp, 1 * kPointerSize));
3167 __ mov(index_2, Operand(esp, 0)); 3155 __ mov(index_2, Operand(esp, 0));
3168 __ mov(temp, index_1); 3156 __ mov(temp, index_1);
3169 __ or_(temp, Operand(index_2)); 3157 __ or_(temp, Operand(index_2));
3170 __ test(temp, Immediate(kSmiTagMask)); 3158 __ JumpIfNotSmi(temp, &slow_case);
3171 __ j(not_zero, &slow_case);
3172 3159
3173 // Check that both indices are valid. 3160 // Check that both indices are valid.
3174 __ mov(temp, FieldOperand(object, JSArray::kLengthOffset)); 3161 __ mov(temp, FieldOperand(object, JSArray::kLengthOffset));
3175 __ cmp(temp, Operand(index_1)); 3162 __ cmp(temp, Operand(index_1));
3176 __ j(below_equal, &slow_case); 3163 __ j(below_equal, &slow_case);
3177 __ cmp(temp, Operand(index_2)); 3164 __ cmp(temp, Operand(index_2));
3178 __ j(below_equal, &slow_case); 3165 __ j(below_equal, &slow_case);
3179 3166
3180 // Bring addresses into index1 and index2. 3167 // Bring addresses into index1 and index2.
3181 __ lea(index_1, CodeGenerator::FixedArrayElementOperand(elements, index_1)); 3168 __ lea(index_1, CodeGenerator::FixedArrayElementOperand(elements, index_1));
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
3266 VisitForStackValue(args->at(0)); 3253 VisitForStackValue(args->at(0));
3267 VisitForAccumulatorValue(args->at(1)); 3254 VisitForAccumulatorValue(args->at(1));
3268 __ pop(left); 3255 __ pop(left);
3269 3256
3270 Label done, fail, ok; 3257 Label done, fail, ok;
3271 __ cmp(left, Operand(right)); 3258 __ cmp(left, Operand(right));
3272 __ j(equal, &ok); 3259 __ j(equal, &ok);
3273 // Fail if either is a non-HeapObject. 3260 // Fail if either is a non-HeapObject.
3274 __ mov(tmp, left); 3261 __ mov(tmp, left);
3275 __ and_(Operand(tmp), right); 3262 __ and_(Operand(tmp), right);
3276 __ test(Operand(tmp), Immediate(kSmiTagMask)); 3263 __ JumpIfSmi(tmp, &fail);
3277 __ j(zero, &fail);
3278 __ mov(tmp, FieldOperand(left, HeapObject::kMapOffset)); 3264 __ mov(tmp, FieldOperand(left, HeapObject::kMapOffset));
3279 __ CmpInstanceType(tmp, JS_REGEXP_TYPE); 3265 __ CmpInstanceType(tmp, JS_REGEXP_TYPE);
3280 __ j(not_equal, &fail); 3266 __ j(not_equal, &fail);
3281 __ cmp(tmp, FieldOperand(right, HeapObject::kMapOffset)); 3267 __ cmp(tmp, FieldOperand(right, HeapObject::kMapOffset));
3282 __ j(not_equal, &fail); 3268 __ j(not_equal, &fail);
3283 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset)); 3269 __ mov(tmp, FieldOperand(left, JSRegExp::kDataOffset));
3284 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset)); 3270 __ cmp(tmp, FieldOperand(right, JSRegExp::kDataOffset));
3285 __ j(equal, &ok); 3271 __ j(equal, &ok);
3286 __ bind(&fail); 3272 __ bind(&fail);
3287 __ mov(eax, Immediate(isolate()->factory()->false_value())); 3273 __ mov(eax, Immediate(isolate()->factory()->false_value()));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
3359 Register array_length = edi; 3345 Register array_length = edi;
3360 Register result_pos = no_reg; // Will be edi. 3346 Register result_pos = no_reg; // Will be edi.
3361 3347
3362 // Separator operand is already pushed. 3348 // Separator operand is already pushed.
3363 Operand separator_operand = Operand(esp, 2 * kPointerSize); 3349 Operand separator_operand = Operand(esp, 2 * kPointerSize);
3364 Operand result_operand = Operand(esp, 1 * kPointerSize); 3350 Operand result_operand = Operand(esp, 1 * kPointerSize);
3365 Operand array_length_operand = Operand(esp, 0); 3351 Operand array_length_operand = Operand(esp, 0);
3366 __ sub(Operand(esp), Immediate(2 * kPointerSize)); 3352 __ sub(Operand(esp), Immediate(2 * kPointerSize));
3367 __ cld(); 3353 __ cld();
3368 // Check that the array is a JSArray 3354 // Check that the array is a JSArray
3369 __ test(array, Immediate(kSmiTagMask)); 3355 __ JumpIfSmi(array, &bailout);
3370 __ j(zero, &bailout);
3371 __ CmpObjectType(array, JS_ARRAY_TYPE, scratch); 3356 __ CmpObjectType(array, JS_ARRAY_TYPE, scratch);
3372 __ j(not_equal, &bailout); 3357 __ j(not_equal, &bailout);
3373 3358
3374 // Check that the array has fast elements. 3359 // Check that the array has fast elements.
3375 __ CheckFastElements(scratch, &bailout); 3360 __ CheckFastElements(scratch, &bailout);
3376 3361
3377 // If the array has length zero, return the empty string. 3362 // If the array has length zero, return the empty string.
3378 __ mov(array_length, FieldOperand(array, JSArray::kLengthOffset)); 3363 __ mov(array_length, FieldOperand(array, JSArray::kLengthOffset));
3379 __ SmiUntag(array_length); 3364 __ SmiUntag(array_length);
3380 __ j(not_zero, &non_trivial_array); 3365 __ j(not_zero, &non_trivial_array);
(...skipping 20 matching lines...) Expand all
3401 // scratch, string_length, elements. 3386 // scratch, string_length, elements.
3402 if (FLAG_debug_code) { 3387 if (FLAG_debug_code) {
3403 __ cmp(index, Operand(array_length)); 3388 __ cmp(index, Operand(array_length));
3404 __ Assert(less, "No empty arrays here in EmitFastAsciiArrayJoin"); 3389 __ Assert(less, "No empty arrays here in EmitFastAsciiArrayJoin");
3405 } 3390 }
3406 __ bind(&loop); 3391 __ bind(&loop);
3407 __ mov(string, FieldOperand(elements, 3392 __ mov(string, FieldOperand(elements,
3408 index, 3393 index,
3409 times_pointer_size, 3394 times_pointer_size,
3410 FixedArray::kHeaderSize)); 3395 FixedArray::kHeaderSize));
3411 __ test(string, Immediate(kSmiTagMask)); 3396 __ JumpIfSmi(string, &bailout);
3412 __ j(zero, &bailout);
3413 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); 3397 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset));
3414 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 3398 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
3415 __ and_(scratch, Immediate( 3399 __ and_(scratch, Immediate(
3416 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); 3400 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
3417 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag); 3401 __ cmp(scratch, kStringTag | kAsciiStringTag | kSeqStringTag);
3418 __ j(not_equal, &bailout); 3402 __ j(not_equal, &bailout);
3419 __ add(string_length, 3403 __ add(string_length,
3420 FieldOperand(string, SeqAsciiString::kLengthOffset)); 3404 FieldOperand(string, SeqAsciiString::kLengthOffset));
3421 __ j(overflow, &bailout); 3405 __ j(overflow, &bailout);
3422 __ add(Operand(index), Immediate(1)); 3406 __ add(Operand(index), Immediate(1));
(...skipping 12 matching lines...) Expand all
3435 // End of array_length live range. 3419 // End of array_length live range.
3436 result_pos = array_length; 3420 result_pos = array_length;
3437 array_length = no_reg; 3421 array_length = no_reg;
3438 3422
3439 // Live registers: 3423 // Live registers:
3440 // string_length: Sum of string lengths, as a smi. 3424 // string_length: Sum of string lengths, as a smi.
3441 // elements: FixedArray of strings. 3425 // elements: FixedArray of strings.
3442 3426
3443 // Check that the separator is a flat ASCII string. 3427 // Check that the separator is a flat ASCII string.
3444 __ mov(string, separator_operand); 3428 __ mov(string, separator_operand);
3445 __ test(string, Immediate(kSmiTagMask)); 3429 __ JumpIfSmi(string, &bailout);
3446 __ j(zero, &bailout);
3447 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset)); 3430 __ mov(scratch, FieldOperand(string, HeapObject::kMapOffset));
3448 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 3431 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
3449 __ and_(scratch, Immediate( 3432 __ and_(scratch, Immediate(
3450 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask)); 3433 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask));
3451 __ cmp(scratch, ASCII_STRING_TYPE); 3434 __ cmp(scratch, ASCII_STRING_TYPE);
3452 __ j(not_equal, &bailout); 3435 __ j(not_equal, &bailout);
3453 3436
3454 // Add (separator length times array_length) - separator length 3437 // Add (separator length times array_length) - separator length
3455 // to string_length. 3438 // to string_length.
3456 __ mov(scratch, separator_operand); 3439 __ mov(scratch, separator_operand);
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
3728 } 3711 }
3729 __ CallRuntime(Runtime::kTypeof, 1); 3712 __ CallRuntime(Runtime::kTypeof, 1);
3730 context()->Plug(eax); 3713 context()->Plug(eax);
3731 break; 3714 break;
3732 } 3715 }
3733 3716
3734 case Token::ADD: { 3717 case Token::ADD: {
3735 Comment cmt(masm_, "[ UnaryOperation (ADD)"); 3718 Comment cmt(masm_, "[ UnaryOperation (ADD)");
3736 VisitForAccumulatorValue(expr->expression()); 3719 VisitForAccumulatorValue(expr->expression());
3737 Label no_conversion; 3720 Label no_conversion;
3738 __ test(result_register(), Immediate(kSmiTagMask)); 3721 __ JumpIfSmi(result_register(), &no_conversion);
3739 __ j(zero, &no_conversion);
3740 ToNumberStub convert_stub; 3722 ToNumberStub convert_stub;
3741 __ CallStub(&convert_stub); 3723 __ CallStub(&convert_stub);
3742 __ bind(&no_conversion); 3724 __ bind(&no_conversion);
3743 context()->Plug(result_register()); 3725 context()->Plug(result_register());
3744 break; 3726 break;
3745 } 3727 }
3746 3728
3747 case Token::SUB: 3729 case Token::SUB:
3748 EmitUnaryOperation(expr, "[ UnaryOperation (SUB)"); 3730 EmitUnaryOperation(expr, "[ UnaryOperation (SUB)");
3749 break; 3731 break;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
3834 // in case evaluating the property load my have a side effect. 3816 // in case evaluating the property load my have a side effect.
3835 if (assign_type == VARIABLE) { 3817 if (assign_type == VARIABLE) {
3836 PrepareForBailout(expr->expression(), TOS_REG); 3818 PrepareForBailout(expr->expression(), TOS_REG);
3837 } else { 3819 } else {
3838 PrepareForBailoutForId(expr->CountId(), TOS_REG); 3820 PrepareForBailoutForId(expr->CountId(), TOS_REG);
3839 } 3821 }
3840 3822
3841 // Call ToNumber only if operand is not a smi. 3823 // Call ToNumber only if operand is not a smi.
3842 Label no_conversion; 3824 Label no_conversion;
3843 if (ShouldInlineSmiCase(expr->op())) { 3825 if (ShouldInlineSmiCase(expr->op())) {
3844 __ test(eax, Immediate(kSmiTagMask)); 3826 __ JumpIfSmi(eax, &no_conversion, Label::kNear);
3845 __ j(zero, &no_conversion, Label::kNear);
3846 } 3827 }
3847 ToNumberStub convert_stub; 3828 ToNumberStub convert_stub;
3848 __ CallStub(&convert_stub); 3829 __ CallStub(&convert_stub);
3849 __ bind(&no_conversion); 3830 __ bind(&no_conversion);
3850 3831
3851 // Save result for postfix expressions. 3832 // Save result for postfix expressions.
3852 if (expr->is_postfix()) { 3833 if (expr->is_postfix()) {
3853 if (!context()->IsEffect()) { 3834 if (!context()->IsEffect()) {
3854 // Save the result on the stack. If we have a named or keyed property 3835 // Save the result on the stack. If we have a named or keyed property
3855 // we store the result under the receiver that is currently on top 3836 // we store the result under the receiver that is currently on top
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
4201 VisitForAccumulatorValue(expr->expression()); 4182 VisitForAccumulatorValue(expr->expression());
4202 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4183 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4203 4184
4204 __ cmp(eax, isolate()->factory()->null_value()); 4185 __ cmp(eax, isolate()->factory()->null_value());
4205 if (expr->is_strict()) { 4186 if (expr->is_strict()) {
4206 Split(equal, if_true, if_false, fall_through); 4187 Split(equal, if_true, if_false, fall_through);
4207 } else { 4188 } else {
4208 __ j(equal, if_true); 4189 __ j(equal, if_true);
4209 __ cmp(eax, isolate()->factory()->undefined_value()); 4190 __ cmp(eax, isolate()->factory()->undefined_value());
4210 __ j(equal, if_true); 4191 __ j(equal, if_true);
4211 __ test(eax, Immediate(kSmiTagMask)); 4192 __ JumpIfSmi(eax, if_false);
4212 __ j(zero, if_false);
4213 // It can be an undetectable object. 4193 // It can be an undetectable object.
4214 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 4194 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
4215 __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset)); 4195 __ movzx_b(edx, FieldOperand(edx, Map::kBitFieldOffset));
4216 __ test(edx, Immediate(1 << Map::kIsUndetectable)); 4196 __ test(edx, Immediate(1 << Map::kIsUndetectable));
4217 Split(not_zero, if_true, if_false, fall_through); 4197 Split(not_zero, if_true, if_false, fall_through);
4218 } 4198 }
4219 context()->Plug(if_true, if_false); 4199 context()->Plug(if_true, if_false);
4220 } 4200 }
4221 4201
4222 4202
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
4328 // And return. 4308 // And return.
4329 __ ret(0); 4309 __ ret(0);
4330 } 4310 }
4331 4311
4332 4312
4333 #undef __ 4313 #undef __
4334 4314
4335 } } // namespace v8::internal 4315 } } // namespace v8::internal
4336 4316
4337 #endif // V8_TARGET_ARCH_IA32 4317 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698