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

Side by Side Diff: src/ia32/builtins-ia32.cc

Issue 1815213002: Extends testb and cmpb/cmpw instruction support in the ia32 assembler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix a copy/pasted erroneous DCHECK. Created 4 years, 9 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
« no previous file with comments | « src/ia32/assembler-ia32-inl.h ('k') | src/ia32/code-stubs-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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 // -- eax : argArray 996 // -- eax : argArray
997 // -- edi : receiver 997 // -- edi : receiver
998 // -- esp[0] : return address 998 // -- esp[0] : return address
999 // -- esp[4] : thisArg 999 // -- esp[4] : thisArg
1000 // ----------------------------------- 1000 // -----------------------------------
1001 1001
1002 // 2. Make sure the receiver is actually callable. 1002 // 2. Make sure the receiver is actually callable.
1003 Label receiver_not_callable; 1003 Label receiver_not_callable;
1004 __ JumpIfSmi(edi, &receiver_not_callable, Label::kNear); 1004 __ JumpIfSmi(edi, &receiver_not_callable, Label::kNear);
1005 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset)); 1005 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1006 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable); 1006 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1007 Immediate(1 << Map::kIsCallable));
1007 __ j(zero, &receiver_not_callable, Label::kNear); 1008 __ j(zero, &receiver_not_callable, Label::kNear);
1008 1009
1009 // 3. Tail call with no arguments if argArray is null or undefined. 1010 // 3. Tail call with no arguments if argArray is null or undefined.
1010 Label no_arguments; 1011 Label no_arguments;
1011 __ JumpIfRoot(eax, Heap::kNullValueRootIndex, &no_arguments, Label::kNear); 1012 __ JumpIfRoot(eax, Heap::kNullValueRootIndex, &no_arguments, Label::kNear);
1012 __ JumpIfRoot(eax, Heap::kUndefinedValueRootIndex, &no_arguments, 1013 __ JumpIfRoot(eax, Heap::kUndefinedValueRootIndex, &no_arguments,
1013 Label::kNear); 1014 Label::kNear);
1014 1015
1015 // 4a. Apply the receiver to the given argArray (passing undefined for 1016 // 4a. Apply the receiver to the given argArray (passing undefined for
1016 // new.target). 1017 // new.target).
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1119 // -- eax : argumentsList 1120 // -- eax : argumentsList
1120 // -- edi : target 1121 // -- edi : target
1121 // -- esp[0] : return address 1122 // -- esp[0] : return address
1122 // -- esp[4] : thisArgument 1123 // -- esp[4] : thisArgument
1123 // ----------------------------------- 1124 // -----------------------------------
1124 1125
1125 // 2. Make sure the target is actually callable. 1126 // 2. Make sure the target is actually callable.
1126 Label target_not_callable; 1127 Label target_not_callable;
1127 __ JumpIfSmi(edi, &target_not_callable, Label::kNear); 1128 __ JumpIfSmi(edi, &target_not_callable, Label::kNear);
1128 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset)); 1129 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1129 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable); 1130 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1131 Immediate(1 << Map::kIsCallable));
1130 __ j(zero, &target_not_callable, Label::kNear); 1132 __ j(zero, &target_not_callable, Label::kNear);
1131 1133
1132 // 3a. Apply the target to the given argumentsList (passing undefined for 1134 // 3a. Apply the target to the given argumentsList (passing undefined for
1133 // new.target). 1135 // new.target).
1134 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex); 1136 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
1135 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); 1137 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1136 1138
1137 // 3b. The target is not callable, throw an appropriate TypeError. 1139 // 3b. The target is not callable, throw an appropriate TypeError.
1138 __ bind(&target_not_callable); 1140 __ bind(&target_not_callable);
1139 { 1141 {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 // -- edx : new.target 1186 // -- edx : new.target
1185 // -- edi : target 1187 // -- edi : target
1186 // -- esp[0] : return address 1188 // -- esp[0] : return address
1187 // -- esp[4] : receiver (undefined) 1189 // -- esp[4] : receiver (undefined)
1188 // ----------------------------------- 1190 // -----------------------------------
1189 1191
1190 // 2. Make sure the target is actually a constructor. 1192 // 2. Make sure the target is actually a constructor.
1191 Label target_not_constructor; 1193 Label target_not_constructor;
1192 __ JumpIfSmi(edi, &target_not_constructor, Label::kNear); 1194 __ JumpIfSmi(edi, &target_not_constructor, Label::kNear);
1193 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset)); 1195 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1194 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor); 1196 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1197 Immediate(1 << Map::kIsConstructor));
1195 __ j(zero, &target_not_constructor, Label::kNear); 1198 __ j(zero, &target_not_constructor, Label::kNear);
1196 1199
1197 // 3. Make sure the target is actually a constructor. 1200 // 3. Make sure the target is actually a constructor.
1198 Label new_target_not_constructor; 1201 Label new_target_not_constructor;
1199 __ JumpIfSmi(edx, &new_target_not_constructor, Label::kNear); 1202 __ JumpIfSmi(edx, &new_target_not_constructor, Label::kNear);
1200 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 1203 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
1201 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor); 1204 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1205 Immediate(1 << Map::kIsConstructor));
1202 __ j(zero, &new_target_not_constructor, Label::kNear); 1206 __ j(zero, &new_target_not_constructor, Label::kNear);
1203 1207
1204 // 4a. Construct the target with the given new.target and argumentsList. 1208 // 4a. Construct the target with the given new.target and argumentsList.
1205 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); 1209 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1206 1210
1207 // 4b. The target is not a constructor, throw an appropriate TypeError. 1211 // 4b. The target is not a constructor, throw an appropriate TypeError.
1208 __ bind(&target_not_constructor); 1212 __ bind(&target_not_constructor);
1209 { 1213 {
1210 __ mov(Operand(esp, kPointerSize), edi); 1214 __ mov(Operand(esp, kPointerSize), edi);
1211 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); 1215 __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
1921 // -- eax : the number of arguments (not including the receiver) 1925 // -- eax : the number of arguments (not including the receiver)
1922 // -- edi : the function to call (checked to be a JSFunction) 1926 // -- edi : the function to call (checked to be a JSFunction)
1923 // ----------------------------------- 1927 // -----------------------------------
1924 __ AssertFunction(edi); 1928 __ AssertFunction(edi);
1925 1929
1926 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) 1930 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1927 // Check that the function is not a "classConstructor". 1931 // Check that the function is not a "classConstructor".
1928 Label class_constructor; 1932 Label class_constructor;
1929 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 1933 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
1930 __ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset), 1934 __ test_b(FieldOperand(edx, SharedFunctionInfo::kFunctionKindByteOffset),
1931 SharedFunctionInfo::kClassConstructorBitsWithinByte); 1935 Immediate(SharedFunctionInfo::kClassConstructorBitsWithinByte));
1932 __ j(not_zero, &class_constructor); 1936 __ j(not_zero, &class_constructor);
1933 1937
1934 // Enter the context of the function; ToObject has to run in the function 1938 // Enter the context of the function; ToObject has to run in the function
1935 // context, and we also need to take the global proxy from the function 1939 // context, and we also need to take the global proxy from the function
1936 // context in case of conversion. 1940 // context in case of conversion.
1937 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset == 1941 STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
1938 SharedFunctionInfo::kStrictModeByteOffset); 1942 SharedFunctionInfo::kStrictModeByteOffset);
1939 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 1943 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
1940 // We need to convert the receiver for non-native sloppy mode functions. 1944 // We need to convert the receiver for non-native sloppy mode functions.
1941 Label done_convert; 1945 Label done_convert;
1942 __ test_b(FieldOperand(edx, SharedFunctionInfo::kNativeByteOffset), 1946 __ test_b(FieldOperand(edx, SharedFunctionInfo::kNativeByteOffset),
1943 (1 << SharedFunctionInfo::kNativeBitWithinByte) | 1947 Immediate((1 << SharedFunctionInfo::kNativeBitWithinByte) |
1944 (1 << SharedFunctionInfo::kStrictModeBitWithinByte)); 1948 (1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
1945 __ j(not_zero, &done_convert); 1949 __ j(not_zero, &done_convert);
1946 { 1950 {
1947 // ----------- S t a t e ------------- 1951 // ----------- S t a t e -------------
1948 // -- eax : the number of arguments (not including the receiver) 1952 // -- eax : the number of arguments (not including the receiver)
1949 // -- edx : the shared function info. 1953 // -- edx : the shared function info.
1950 // -- edi : the function to call (checked to be a JSFunction) 1954 // -- edi : the function to call (checked to be a JSFunction)
1951 // -- esi : the function context. 1955 // -- esi : the function context.
1952 // ----------------------------------- 1956 // -----------------------------------
1953 1957
1954 if (mode == ConvertReceiverMode::kNullOrUndefined) { 1958 if (mode == ConvertReceiverMode::kNullOrUndefined) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
2156 __ JumpIfSmi(edi, &non_callable); 2160 __ JumpIfSmi(edi, &non_callable);
2157 __ bind(&non_smi); 2161 __ bind(&non_smi);
2158 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 2162 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2159 __ j(equal, masm->isolate()->builtins()->CallFunction(mode, tail_call_mode), 2163 __ j(equal, masm->isolate()->builtins()->CallFunction(mode, tail_call_mode),
2160 RelocInfo::CODE_TARGET); 2164 RelocInfo::CODE_TARGET);
2161 __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE); 2165 __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
2162 __ j(equal, masm->isolate()->builtins()->CallBoundFunction(tail_call_mode), 2166 __ j(equal, masm->isolate()->builtins()->CallBoundFunction(tail_call_mode),
2163 RelocInfo::CODE_TARGET); 2167 RelocInfo::CODE_TARGET);
2164 2168
2165 // Check if target has a [[Call]] internal method. 2169 // Check if target has a [[Call]] internal method.
2166 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable); 2170 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
2171 Immediate(1 << Map::kIsCallable));
2167 __ j(zero, &non_callable); 2172 __ j(zero, &non_callable);
2168 2173
2169 __ CmpInstanceType(ecx, JS_PROXY_TYPE); 2174 __ CmpInstanceType(ecx, JS_PROXY_TYPE);
2170 __ j(not_equal, &non_function); 2175 __ j(not_equal, &non_function);
2171 2176
2172 // 0. Prepare for tail call if necessary. 2177 // 0. Prepare for tail call if necessary.
2173 if (tail_call_mode == TailCallMode::kAllow) { 2178 if (tail_call_mode == TailCallMode::kAllow) {
2174 PrepareForTailCall(masm, eax, ebx, ecx, edx); 2179 PrepareForTailCall(masm, eax, ebx, ecx, edx);
2175 } 2180 }
2176 2181
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
2292 // Check if target is a Smi. 2297 // Check if target is a Smi.
2293 Label non_constructor; 2298 Label non_constructor;
2294 __ JumpIfSmi(edi, &non_constructor, Label::kNear); 2299 __ JumpIfSmi(edi, &non_constructor, Label::kNear);
2295 2300
2296 // Dispatch based on instance type. 2301 // Dispatch based on instance type.
2297 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 2302 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
2298 __ j(equal, masm->isolate()->builtins()->ConstructFunction(), 2303 __ j(equal, masm->isolate()->builtins()->ConstructFunction(),
2299 RelocInfo::CODE_TARGET); 2304 RelocInfo::CODE_TARGET);
2300 2305
2301 // Check if target has a [[Construct]] internal method. 2306 // Check if target has a [[Construct]] internal method.
2302 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor); 2307 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
2308 Immediate(1 << Map::kIsConstructor));
2303 __ j(zero, &non_constructor, Label::kNear); 2309 __ j(zero, &non_constructor, Label::kNear);
2304 2310
2305 // Only dispatch to bound functions after checking whether they are 2311 // Only dispatch to bound functions after checking whether they are
2306 // constructors. 2312 // constructors.
2307 __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE); 2313 __ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
2308 __ j(equal, masm->isolate()->builtins()->ConstructBoundFunction(), 2314 __ j(equal, masm->isolate()->builtins()->ConstructBoundFunction(),
2309 RelocInfo::CODE_TARGET); 2315 RelocInfo::CODE_TARGET);
2310 2316
2311 // Only dispatch to proxies after checking whether they are constructors. 2317 // Only dispatch to proxies after checking whether they are constructors.
2312 __ CmpInstanceType(ecx, JS_PROXY_TYPE); 2318 __ CmpInstanceType(ecx, JS_PROXY_TYPE);
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
2582 // And "return" to the OSR entry point of the function. 2588 // And "return" to the OSR entry point of the function.
2583 __ ret(0); 2589 __ ret(0);
2584 } 2590 }
2585 2591
2586 2592
2587 #undef __ 2593 #undef __
2588 } // namespace internal 2594 } // namespace internal
2589 } // namespace v8 2595 } // namespace v8
2590 2596
2591 #endif // V8_TARGET_ARCH_IA32 2597 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/assembler-ia32-inl.h ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698