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

Side by Side Diff: src/ia32/code-stubs-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/builtins-ia32.cc ('k') | src/ia32/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 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-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/api-arguments.h" 8 #include "src/api-arguments.h"
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 __ fxch(1); // X - rnd(X), rnd(X) 547 __ fxch(1); // X - rnd(X), rnd(X)
548 // F2XM1 calculates 2^st(0) - 1 for -1 < st(0) < 1 548 // F2XM1 calculates 2^st(0) - 1 for -1 < st(0) < 1
549 __ f2xm1(); // 2^(X-rnd(X)) - 1, rnd(X) 549 __ f2xm1(); // 2^(X-rnd(X)) - 1, rnd(X)
550 __ fld1(); // 1, 2^(X-rnd(X)) - 1, rnd(X) 550 __ fld1(); // 1, 2^(X-rnd(X)) - 1, rnd(X)
551 __ faddp(1); // 2^(X-rnd(X)), rnd(X) 551 __ faddp(1); // 2^(X-rnd(X)), rnd(X)
552 // FSCALE calculates st(0) * 2^st(1) 552 // FSCALE calculates st(0) * 2^st(1)
553 __ fscale(); // 2^X, rnd(X) 553 __ fscale(); // 2^X, rnd(X)
554 __ fstp(1); // 2^X 554 __ fstp(1); // 2^X
555 // Bail out to runtime in case of exceptions in the status word. 555 // Bail out to runtime in case of exceptions in the status word.
556 __ fnstsw_ax(); 556 __ fnstsw_ax();
557 __ test_b(eax, 0x5F); // We check for all but precision exception. 557 __ test_b(eax,
558 Immediate(0x5F)); // We check for all but precision exception.
558 __ j(not_zero, &fast_power_failed, Label::kNear); 559 __ j(not_zero, &fast_power_failed, Label::kNear);
559 __ fstp_d(Operand(esp, 0)); 560 __ fstp_d(Operand(esp, 0));
560 __ movsd(double_result, Operand(esp, 0)); 561 __ movsd(double_result, Operand(esp, 0));
561 __ add(esp, Immediate(kDoubleSize)); 562 __ add(esp, Immediate(kDoubleSize));
562 __ jmp(&done); 563 __ jmp(&done);
563 564
564 __ bind(&fast_power_failed); 565 __ bind(&fast_power_failed);
565 __ fninit(); 566 __ fninit();
566 __ add(esp, Immediate(kDoubleSize)); 567 __ add(esp, Immediate(kDoubleSize));
567 __ jmp(&call_runtime); 568 __ jmp(&call_runtime);
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 // (4) Cons string. Check that it's flat. 860 // (4) Cons string. Check that it's flat.
860 // Replace subject with first string and reload instance type. 861 // Replace subject with first string and reload instance type.
861 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string()); 862 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string());
862 __ j(not_equal, &runtime); 863 __ j(not_equal, &runtime);
863 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); 864 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
864 __ bind(&check_underlying); 865 __ bind(&check_underlying);
865 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 866 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
866 __ mov(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 867 __ mov(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
867 868
868 // (5a) Is subject sequential two byte? If yes, go to (9). 869 // (5a) Is subject sequential two byte? If yes, go to (9).
869 __ test_b(ebx, kStringRepresentationMask | kStringEncodingMask); 870 __ test_b(ebx, Immediate(kStringRepresentationMask | kStringEncodingMask));
870 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); 871 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
871 __ j(zero, &seq_two_byte_string); // Go to (9). 872 __ j(zero, &seq_two_byte_string); // Go to (9).
872 // (5b) Is subject external? If yes, go to (8). 873 // (5b) Is subject external? If yes, go to (8).
873 __ test_b(ebx, kStringRepresentationMask); 874 __ test_b(ebx, Immediate(kStringRepresentationMask));
874 // The underlying external string is never a short external string. 875 // The underlying external string is never a short external string.
875 STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength); 876 STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
876 STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength); 877 STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
877 __ j(not_zero, &external_string); // Go to (8). 878 __ j(not_zero, &external_string); // Go to (8).
878 879
879 // eax: sequential subject string (or look-alike, external string) 880 // eax: sequential subject string (or look-alike, external string)
880 // edx: original subject string 881 // edx: original subject string
881 // ecx: RegExp data (FixedArray) 882 // ecx: RegExp data (FixedArray)
882 // (6) One byte sequential. Load regexp code for one byte. 883 // (6) One byte sequential. Load regexp code for one byte.
883 __ bind(&seq_one_byte_string); 884 __ bind(&seq_one_byte_string);
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 __ j(greater, &not_long_external, Label::kNear); // Go to (10). 1113 __ j(greater, &not_long_external, Label::kNear); // Go to (10).
1113 1114
1114 // (8) External string. Short external strings have been ruled out. 1115 // (8) External string. Short external strings have been ruled out.
1115 __ bind(&external_string); 1116 __ bind(&external_string);
1116 // Reload instance type. 1117 // Reload instance type.
1117 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 1118 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
1118 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 1119 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
1119 if (FLAG_debug_code) { 1120 if (FLAG_debug_code) {
1120 // Assert that we do not have a cons or slice (indirect strings) here. 1121 // Assert that we do not have a cons or slice (indirect strings) here.
1121 // Sequential strings have already been ruled out. 1122 // Sequential strings have already been ruled out.
1122 __ test_b(ebx, kIsIndirectStringMask); 1123 __ test_b(ebx, Immediate(kIsIndirectStringMask));
1123 __ Assert(zero, kExternalStringExpectedButNotFound); 1124 __ Assert(zero, kExternalStringExpectedButNotFound);
1124 } 1125 }
1125 __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset)); 1126 __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset));
1126 // Move the pointer so that offset-wise, it looks like a sequential string. 1127 // Move the pointer so that offset-wise, it looks like a sequential string.
1127 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 1128 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
1128 __ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 1129 __ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
1129 STATIC_ASSERT(kTwoByteStringTag == 0); 1130 STATIC_ASSERT(kTwoByteStringTag == 0);
1130 // (8a) Is the external string one byte? If yes, go to (6). 1131 // (8a) Is the external string one byte? If yes, go to (6).
1131 __ test_b(ebx, kStringEncodingMask); 1132 __ test_b(ebx, Immediate(kStringEncodingMask));
1132 __ j(not_zero, &seq_one_byte_string); // Goto (6). 1133 __ j(not_zero, &seq_one_byte_string); // Goto (6).
1133 1134
1134 // eax: sequential subject string (or look-alike, external string) 1135 // eax: sequential subject string (or look-alike, external string)
1135 // edx: original subject string 1136 // edx: original subject string
1136 // ecx: RegExp data (FixedArray) 1137 // ecx: RegExp data (FixedArray)
1137 // (9) Two byte sequential. Load regexp code for one byte. Go to (E). 1138 // (9) Two byte sequential. Load regexp code for one byte. Go to (E).
1138 __ bind(&seq_two_byte_string); 1139 __ bind(&seq_two_byte_string);
1139 // Load previous index and check range before edx is overwritten. We have 1140 // Load previous index and check range before edx is overwritten. We have
1140 // to use edx instead of eax here because it might have been only made to 1141 // to use edx instead of eax here because it might have been only made to
1141 // look like a sequential string when it actually is an external string. 1142 // look like a sequential string when it actually is an external string.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 1247
1247 // Test for NaN. Compare heap numbers in a general way, 1248 // Test for NaN. Compare heap numbers in a general way,
1248 // to handle NaNs correctly. 1249 // to handle NaNs correctly.
1249 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 1250 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
1250 Immediate(isolate()->factory()->heap_number_map())); 1251 Immediate(isolate()->factory()->heap_number_map()));
1251 __ j(equal, &generic_heap_number_comparison, Label::kNear); 1252 __ j(equal, &generic_heap_number_comparison, Label::kNear);
1252 if (cc != equal) { 1253 if (cc != equal) {
1253 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 1254 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
1254 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 1255 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
1255 // Call runtime on identical JSObjects. Otherwise return equal. 1256 // Call runtime on identical JSObjects. Otherwise return equal.
1256 __ cmpb(ecx, static_cast<uint8_t>(FIRST_JS_RECEIVER_TYPE)); 1257 __ cmpb(ecx, Immediate(FIRST_JS_RECEIVER_TYPE));
1257 __ j(above_equal, &runtime_call, Label::kFar); 1258 __ j(above_equal, &runtime_call, Label::kFar);
1258 // Call runtime on identical symbols since we need to throw a TypeError. 1259 // Call runtime on identical symbols since we need to throw a TypeError.
1259 __ cmpb(ecx, static_cast<uint8_t>(SYMBOL_TYPE)); 1260 __ cmpb(ecx, Immediate(SYMBOL_TYPE));
1260 __ j(equal, &runtime_call, Label::kFar); 1261 __ j(equal, &runtime_call, Label::kFar);
1261 // Call runtime on identical SIMD values since we must throw a TypeError. 1262 // Call runtime on identical SIMD values since we must throw a TypeError.
1262 __ cmpb(ecx, static_cast<uint8_t>(SIMD128_VALUE_TYPE)); 1263 __ cmpb(ecx, Immediate(SIMD128_VALUE_TYPE));
1263 __ j(equal, &runtime_call, Label::kFar); 1264 __ j(equal, &runtime_call, Label::kFar);
1264 } 1265 }
1265 __ Move(eax, Immediate(Smi::FromInt(EQUAL))); 1266 __ Move(eax, Immediate(Smi::FromInt(EQUAL)));
1266 __ ret(0); 1267 __ ret(0);
1267 1268
1268 1269
1269 __ bind(&not_identical); 1270 __ bind(&not_identical);
1270 } 1271 }
1271 1272
1272 // Strict equality can quickly decide whether objects are equal. 1273 // Strict equality can quickly decide whether objects are equal.
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 STATIC_ASSERT(kSmiTag == 0); 1413 STATIC_ASSERT(kSmiTag == 0);
1413 STATIC_ASSERT(kSmiTagMask == 1); 1414 STATIC_ASSERT(kSmiTagMask == 1);
1414 __ lea(ecx, Operand(eax, edx, times_1, 0)); 1415 __ lea(ecx, Operand(eax, edx, times_1, 0));
1415 __ test(ecx, Immediate(kSmiTagMask)); 1416 __ test(ecx, Immediate(kSmiTagMask));
1416 __ j(not_zero, &runtime_call); 1417 __ j(not_zero, &runtime_call);
1417 1418
1418 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 1419 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
1419 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); 1420 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset));
1420 1421
1421 __ test_b(FieldOperand(ebx, Map::kBitFieldOffset), 1422 __ test_b(FieldOperand(ebx, Map::kBitFieldOffset),
1422 1 << Map::kIsUndetectable); 1423 Immediate(1 << Map::kIsUndetectable));
1423 __ j(not_zero, &undetectable, Label::kNear); 1424 __ j(not_zero, &undetectable, Label::kNear);
1424 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1425 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1425 1 << Map::kIsUndetectable); 1426 Immediate(1 << Map::kIsUndetectable));
1426 __ j(not_zero, &return_unequal, Label::kNear); 1427 __ j(not_zero, &return_unequal, Label::kNear);
1427 1428
1428 __ CmpInstanceType(ebx, FIRST_JS_RECEIVER_TYPE); 1429 __ CmpInstanceType(ebx, FIRST_JS_RECEIVER_TYPE);
1429 __ j(below, &runtime_call, Label::kNear); 1430 __ j(below, &runtime_call, Label::kNear);
1430 __ CmpInstanceType(ecx, FIRST_JS_RECEIVER_TYPE); 1431 __ CmpInstanceType(ecx, FIRST_JS_RECEIVER_TYPE);
1431 __ j(below, &runtime_call, Label::kNear); 1432 __ j(below, &runtime_call, Label::kNear);
1432 1433
1433 __ bind(&return_unequal); 1434 __ bind(&return_unequal);
1434 // Return non-equal by returning the non-zero object pointer in eax. 1435 // Return non-equal by returning the non-zero object pointer in eax.
1435 __ ret(0); // eax, edx were pushed 1436 __ ret(0); // eax, edx were pushed
1436 1437
1437 __ bind(&undetectable); 1438 __ bind(&undetectable);
1438 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1439 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
1439 1 << Map::kIsUndetectable); 1440 Immediate(1 << Map::kIsUndetectable));
1440 __ j(zero, &return_unequal, Label::kNear); 1441 __ j(zero, &return_unequal, Label::kNear);
1441 1442
1442 // If both sides are JSReceivers, then the result is false according to 1443 // If both sides are JSReceivers, then the result is false according to
1443 // the HTML specification, which says that only comparisons with null or 1444 // the HTML specification, which says that only comparisons with null or
1444 // undefined are affected by special casing for document.all. 1445 // undefined are affected by special casing for document.all.
1445 __ CmpInstanceType(ebx, ODDBALL_TYPE); 1446 __ CmpInstanceType(ebx, ODDBALL_TYPE);
1446 __ j(zero, &return_equal, Label::kNear); 1447 __ j(zero, &return_equal, Label::kNear);
1447 __ CmpInstanceType(ecx, ODDBALL_TYPE); 1448 __ CmpInstanceType(ecx, ODDBALL_TYPE);
1448 __ j(not_zero, &return_unequal, Label::kNear); 1449 __ j(not_zero, &return_unequal, Label::kNear);
1449 1450
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
2132 __ ret(0); 2133 __ ret(0);
2133 2134
2134 // Fast-case: The {function} must be a valid JSFunction. 2135 // Fast-case: The {function} must be a valid JSFunction.
2135 __ bind(&fast_case); 2136 __ bind(&fast_case);
2136 __ JumpIfSmi(function, &slow_case); 2137 __ JumpIfSmi(function, &slow_case);
2137 __ CmpObjectType(function, JS_FUNCTION_TYPE, function_map); 2138 __ CmpObjectType(function, JS_FUNCTION_TYPE, function_map);
2138 __ j(not_equal, &slow_case); 2139 __ j(not_equal, &slow_case);
2139 2140
2140 // Go to the runtime if the function is not a constructor. 2141 // Go to the runtime if the function is not a constructor.
2141 __ test_b(FieldOperand(function_map, Map::kBitFieldOffset), 2142 __ test_b(FieldOperand(function_map, Map::kBitFieldOffset),
2142 static_cast<uint8_t>(1 << Map::kIsConstructor)); 2143 Immediate(1 << Map::kIsConstructor));
2143 __ j(zero, &slow_case); 2144 __ j(zero, &slow_case);
2144 2145
2145 // Ensure that {function} has an instance prototype. 2146 // Ensure that {function} has an instance prototype.
2146 __ test_b(FieldOperand(function_map, Map::kBitFieldOffset), 2147 __ test_b(FieldOperand(function_map, Map::kBitFieldOffset),
2147 static_cast<uint8_t>(1 << Map::kHasNonInstancePrototype)); 2148 Immediate(1 << Map::kHasNonInstancePrototype));
2148 __ j(not_zero, &slow_case); 2149 __ j(not_zero, &slow_case);
2149 2150
2150 // Get the "prototype" (or initial map) of the {function}. 2151 // Get the "prototype" (or initial map) of the {function}.
2151 __ mov(function_prototype, 2152 __ mov(function_prototype,
2152 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 2153 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
2153 __ AssertNotSmi(function_prototype); 2154 __ AssertNotSmi(function_prototype);
2154 2155
2155 // Resolve the prototype if the {function} has an initial map. Afterwards the 2156 // Resolve the prototype if the {function} has an initial map. Afterwards the
2156 // {function_prototype} will be either the JSReceiver prototype object or the 2157 // {function_prototype} will be either the JSReceiver prototype object or the
2157 // hole value, which means that no instances of the {function} were created so 2158 // hole value, which means that no instances of the {function} were created so
(...skipping 13 matching lines...) Expand all
2171 __ StoreRoot(object_map, scratch, Heap::kInstanceofCacheMapRootIndex); 2172 __ StoreRoot(object_map, scratch, Heap::kInstanceofCacheMapRootIndex);
2172 2173
2173 // Loop through the prototype chain looking for the {function} prototype. 2174 // Loop through the prototype chain looking for the {function} prototype.
2174 // Assume true, and change to false if not found. 2175 // Assume true, and change to false if not found.
2175 Label done, loop, fast_runtime_fallback; 2176 Label done, loop, fast_runtime_fallback;
2176 __ mov(eax, isolate()->factory()->true_value()); 2177 __ mov(eax, isolate()->factory()->true_value());
2177 __ bind(&loop); 2178 __ bind(&loop);
2178 2179
2179 // Check if the object needs to be access checked. 2180 // Check if the object needs to be access checked.
2180 __ test_b(FieldOperand(object_map, Map::kBitFieldOffset), 2181 __ test_b(FieldOperand(object_map, Map::kBitFieldOffset),
2181 1 << Map::kIsAccessCheckNeeded); 2182 Immediate(1 << Map::kIsAccessCheckNeeded));
2182 __ j(not_zero, &fast_runtime_fallback, Label::kNear); 2183 __ j(not_zero, &fast_runtime_fallback, Label::kNear);
2183 // Check if the current object is a Proxy. 2184 // Check if the current object is a Proxy.
2184 __ CmpInstanceType(object_map, JS_PROXY_TYPE); 2185 __ CmpInstanceType(object_map, JS_PROXY_TYPE);
2185 __ j(equal, &fast_runtime_fallback, Label::kNear); 2186 __ j(equal, &fast_runtime_fallback, Label::kNear);
2186 2187
2187 __ mov(object, FieldOperand(object_map, Map::kPrototypeOffset)); 2188 __ mov(object, FieldOperand(object_map, Map::kPrototypeOffset));
2188 __ cmp(object, function_prototype); 2189 __ cmp(object, function_prototype);
2189 __ j(equal, &done, Label::kNear); 2190 __ j(equal, &done, Label::kNear);
2190 __ mov(object_map, FieldOperand(object, HeapObject::kMapOffset)); 2191 __ mov(object_map, FieldOperand(object, HeapObject::kMapOffset));
2191 __ cmp(object, isolate()->factory()->null_value()); 2192 __ cmp(object, isolate()->factory()->null_value());
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
2518 2519
2519 // edi: underlying subject string 2520 // edi: underlying subject string
2520 // ebx: instance type of underlying subject string 2521 // ebx: instance type of underlying subject string
2521 // edx: adjusted start index (smi) 2522 // edx: adjusted start index (smi)
2522 // ecx: length (smi) 2523 // ecx: length (smi)
2523 // The subject string can only be external or sequential string of either 2524 // The subject string can only be external or sequential string of either
2524 // encoding at this point. 2525 // encoding at this point.
2525 Label two_byte_sequential, runtime_drop_two, sequential_string; 2526 Label two_byte_sequential, runtime_drop_two, sequential_string;
2526 STATIC_ASSERT(kExternalStringTag != 0); 2527 STATIC_ASSERT(kExternalStringTag != 0);
2527 STATIC_ASSERT(kSeqStringTag == 0); 2528 STATIC_ASSERT(kSeqStringTag == 0);
2528 __ test_b(ebx, kExternalStringTag); 2529 __ test_b(ebx, Immediate(kExternalStringTag));
2529 __ j(zero, &sequential_string); 2530 __ j(zero, &sequential_string);
2530 2531
2531 // Handle external string. 2532 // Handle external string.
2532 // Rule out short external strings. 2533 // Rule out short external strings.
2533 STATIC_ASSERT(kShortExternalStringTag != 0); 2534 STATIC_ASSERT(kShortExternalStringTag != 0);
2534 __ test_b(ebx, kShortExternalStringMask); 2535 __ test_b(ebx, Immediate(kShortExternalStringMask));
2535 __ j(not_zero, &runtime); 2536 __ j(not_zero, &runtime);
2536 __ mov(edi, FieldOperand(edi, ExternalString::kResourceDataOffset)); 2537 __ mov(edi, FieldOperand(edi, ExternalString::kResourceDataOffset));
2537 // Move the pointer so that offset-wise, it looks like a sequential string. 2538 // Move the pointer so that offset-wise, it looks like a sequential string.
2538 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 2539 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
2539 __ sub(edi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 2540 __ sub(edi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
2540 2541
2541 __ bind(&sequential_string); 2542 __ bind(&sequential_string);
2542 // Stash away (adjusted) index and (underlying) string. 2543 // Stash away (adjusted) index and (underlying) string.
2543 __ push(edx); 2544 __ push(edx);
2544 __ push(edi); 2545 __ push(edi);
2545 __ SmiUntag(ecx); 2546 __ SmiUntag(ecx);
2546 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 2547 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
2547 __ test_b(ebx, kStringEncodingMask); 2548 __ test_b(ebx, Immediate(kStringEncodingMask));
2548 __ j(zero, &two_byte_sequential); 2549 __ j(zero, &two_byte_sequential);
2549 2550
2550 // Sequential one byte string. Allocate the result. 2551 // Sequential one byte string. Allocate the result.
2551 __ AllocateOneByteString(eax, ecx, ebx, edx, edi, &runtime_drop_two); 2552 __ AllocateOneByteString(eax, ecx, ebx, edx, edi, &runtime_drop_two);
2552 2553
2553 // eax: result string 2554 // eax: result string
2554 // ecx: result string length 2555 // ecx: result string length
2555 // Locate first character of result. 2556 // Locate first character of result.
2556 __ mov(edi, eax); 2557 __ mov(edi, eax);
2557 __ add(edi, Immediate(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 2558 __ add(edi, Immediate(SeqOneByteString::kHeaderSize - kHeapObjectTag));
(...skipping 1879 matching lines...) Expand 10 before | Expand all | Expand 10 after
4437 Label normal_sequence; 4438 Label normal_sequence;
4438 if (mode == DONT_OVERRIDE) { 4439 if (mode == DONT_OVERRIDE) {
4439 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 4440 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
4440 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 4441 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
4441 STATIC_ASSERT(FAST_ELEMENTS == 2); 4442 STATIC_ASSERT(FAST_ELEMENTS == 2);
4442 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 4443 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
4443 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS == 4); 4444 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS == 4);
4444 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); 4445 STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
4445 4446
4446 // is the low bit set? If so, we are holey and that is good. 4447 // is the low bit set? If so, we are holey and that is good.
4447 __ test_b(edx, 1); 4448 __ test_b(edx, Immediate(1));
4448 __ j(not_zero, &normal_sequence); 4449 __ j(not_zero, &normal_sequence);
4449 } 4450 }
4450 4451
4451 // look at the first argument 4452 // look at the first argument
4452 __ mov(ecx, Operand(esp, kPointerSize)); 4453 __ mov(ecx, Operand(esp, kPointerSize));
4453 __ test(ecx, ecx); 4454 __ test(ecx, ecx);
4454 __ j(zero, &normal_sequence); 4455 __ j(zero, &normal_sequence);
4455 4456
4456 if (mode == DISABLE_ALLOCATION_SITES) { 4457 if (mode == DISABLE_ALLOCATION_SITES) {
4457 ElementsKind initial = GetInitialFastElementsKind(); 4458 ElementsKind initial = GetInitialFastElementsKind();
(...skipping 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after
5581 Immediate(ExternalReference::isolate_address(isolate))); 5582 Immediate(ExternalReference::isolate_address(isolate)));
5582 __ CallCFunction(ExternalReference::log_enter_external_function(isolate), 5583 __ CallCFunction(ExternalReference::log_enter_external_function(isolate),
5583 1); 5584 1);
5584 __ PopSafepointRegisters(); 5585 __ PopSafepointRegisters();
5585 } 5586 }
5586 5587
5587 5588
5588 Label profiler_disabled; 5589 Label profiler_disabled;
5589 Label end_profiler_check; 5590 Label end_profiler_check;
5590 __ mov(eax, Immediate(ExternalReference::is_profiling_address(isolate))); 5591 __ mov(eax, Immediate(ExternalReference::is_profiling_address(isolate)));
5591 __ cmpb(Operand(eax, 0), 0); 5592 __ cmpb(Operand(eax, 0), Immediate(0));
5592 __ j(zero, &profiler_disabled); 5593 __ j(zero, &profiler_disabled);
5593 5594
5594 // Additional parameter is the address of the actual getter function. 5595 // Additional parameter is the address of the actual getter function.
5595 __ mov(thunk_last_arg, function_address); 5596 __ mov(thunk_last_arg, function_address);
5596 // Call the api function. 5597 // Call the api function.
5597 __ mov(eax, Immediate(thunk_ref)); 5598 __ mov(eax, Immediate(thunk_ref));
5598 __ call(eax); 5599 __ call(eax);
5599 __ jmp(&end_profiler_check); 5600 __ jmp(&end_profiler_check);
5600 5601
5601 __ bind(&profiler_disabled); 5602 __ bind(&profiler_disabled);
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
5880 return_value_operand, NULL); 5881 return_value_operand, NULL);
5881 } 5882 }
5882 5883
5883 5884
5884 #undef __ 5885 #undef __
5885 5886
5886 } // namespace internal 5887 } // namespace internal
5887 } // namespace v8 5888 } // namespace v8
5888 5889
5889 #endif // V8_TARGET_ARCH_IA32 5890 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/builtins-ia32.cc ('k') | src/ia32/codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698