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

Side by Side Diff: src/mips/code-stubs-mips.cc

Issue 139973004: A64: Synchronize with r15814. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/mips/code-stubs-mips.h ('k') | src/mips/codegen-mips.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 // 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 21 matching lines...) Expand all
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "code-stubs.h" 33 #include "code-stubs.h"
34 #include "codegen.h" 34 #include "codegen.h"
35 #include "regexp-macro-assembler.h" 35 #include "regexp-macro-assembler.h"
36 #include "stub-cache.h" 36 #include "stub-cache.h"
37 37
38 namespace v8 { 38 namespace v8 {
39 namespace internal { 39 namespace internal {
40 40
41 41
42 void ToNumberStub::InitializeInterfaceDescriptor(
43 Isolate* isolate,
44 CodeStubInterfaceDescriptor* descriptor) {
45 static Register registers[] = { a0 };
46 descriptor->register_param_count_ = 1;
47 descriptor->register_params_ = registers;
48 descriptor->deoptimization_handler_ = NULL;
49 }
50
51
42 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor( 52 void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
43 Isolate* isolate, 53 Isolate* isolate,
44 CodeStubInterfaceDescriptor* descriptor) { 54 CodeStubInterfaceDescriptor* descriptor) {
45 static Register registers[] = { a3, a2, a1 }; 55 static Register registers[] = { a3, a2, a1 };
46 descriptor->register_param_count_ = 3; 56 descriptor->register_param_count_ = 3;
47 descriptor->register_params_ = registers; 57 descriptor->register_params_ = registers;
48 descriptor->deoptimization_handler_ = 58 descriptor->deoptimization_handler_ =
49 Runtime::FunctionForId(Runtime::kCreateArrayLiteralShallow)->entry; 59 Runtime::FunctionForId(Runtime::kCreateArrayLiteralShallow)->entry;
50 } 60 }
51 61
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 Isolate* isolate, 262 Isolate* isolate,
253 CodeStubInterfaceDescriptor* descriptor) { 263 CodeStubInterfaceDescriptor* descriptor) {
254 static Register registers[] = { a1, a2, a0 }; 264 static Register registers[] = { a1, a2, a0 };
255 descriptor->register_param_count_ = 3; 265 descriptor->register_param_count_ = 3;
256 descriptor->register_params_ = registers; 266 descriptor->register_params_ = registers;
257 descriptor->deoptimization_handler_ = 267 descriptor->deoptimization_handler_ =
258 FUNCTION_ADDR(StoreIC_MissFromStubFailure); 268 FUNCTION_ADDR(StoreIC_MissFromStubFailure);
259 } 269 }
260 270
261 271
272 void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
273 Isolate* isolate,
274 CodeStubInterfaceDescriptor* descriptor) {
275 static Register registers[] = { a0, a3, a1, a2 };
276 descriptor->register_param_count_ = 4;
277 descriptor->register_params_ = registers;
278 descriptor->deoptimization_handler_ =
279 FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss);
280 }
281
282
262 #define __ ACCESS_MASM(masm) 283 #define __ ACCESS_MASM(masm)
263 284
264 285
265 static void EmitIdenticalObjectComparison(MacroAssembler* masm, 286 static void EmitIdenticalObjectComparison(MacroAssembler* masm,
266 Label* slow, 287 Label* slow,
267 Condition cc); 288 Condition cc);
268 static void EmitSmiNonsmiComparison(MacroAssembler* masm, 289 static void EmitSmiNonsmiComparison(MacroAssembler* masm,
269 Register lhs, 290 Register lhs,
270 Register rhs, 291 Register rhs,
271 Label* rhs_not_nan, 292 Label* rhs_not_nan,
272 Label* slow, 293 Label* slow,
273 bool strict); 294 bool strict);
274 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, 295 static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
275 Register lhs, 296 Register lhs,
276 Register rhs); 297 Register rhs);
277 298
278 299
279 // Check if the operand is a heap number.
280 static void EmitCheckForHeapNumber(MacroAssembler* masm, Register operand,
281 Register scratch1, Register scratch2,
282 Label* not_a_heap_number) {
283 __ lw(scratch1, FieldMemOperand(operand, HeapObject::kMapOffset));
284 __ LoadRoot(scratch2, Heap::kHeapNumberMapRootIndex);
285 __ Branch(not_a_heap_number, ne, scratch1, Operand(scratch2));
286 }
287
288
289 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { 300 void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
290 // Update the static counter each time a new code stub is generated. 301 // Update the static counter each time a new code stub is generated.
291 Isolate* isolate = masm->isolate(); 302 Isolate* isolate = masm->isolate();
292 isolate->counters()->code_stubs()->Increment(); 303 isolate->counters()->code_stubs()->Increment();
293 304
294 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate); 305 CodeStubInterfaceDescriptor* descriptor = GetInterfaceDescriptor(isolate);
295 int param_count = descriptor->register_param_count_; 306 int param_count = descriptor->register_param_count_;
296 { 307 {
297 // Call the runtime system in a fresh internal frame. 308 // Call the runtime system in a fresh internal frame.
298 FrameScope scope(masm, StackFrame::INTERNAL); 309 FrameScope scope(masm, StackFrame::INTERNAL);
299 ASSERT(descriptor->register_param_count_ == 0 || 310 ASSERT(descriptor->register_param_count_ == 0 ||
300 a0.is(descriptor->register_params_[param_count - 1])); 311 a0.is(descriptor->register_params_[param_count - 1]));
301 // Push arguments 312 // Push arguments
302 for (int i = 0; i < param_count; ++i) { 313 for (int i = 0; i < param_count; ++i) {
303 __ push(descriptor->register_params_[i]); 314 __ push(descriptor->register_params_[i]);
304 } 315 }
305 ExternalReference miss = descriptor->miss_handler(); 316 ExternalReference miss = descriptor->miss_handler();
306 __ CallExternalReference(miss, descriptor->register_param_count_); 317 __ CallExternalReference(miss, descriptor->register_param_count_);
307 } 318 }
308 319
309 __ Ret(); 320 __ Ret();
310 } 321 }
311 322
312 323
313 void ToNumberStub::Generate(MacroAssembler* masm) {
314 // The ToNumber stub takes one argument in a0.
315 Label check_heap_number, call_builtin;
316 __ JumpIfNotSmi(a0, &check_heap_number);
317 __ Ret(USE_DELAY_SLOT);
318 __ mov(v0, a0);
319
320 __ bind(&check_heap_number);
321 EmitCheckForHeapNumber(masm, a0, a1, t0, &call_builtin);
322 __ Ret(USE_DELAY_SLOT);
323 __ mov(v0, a0);
324
325 __ bind(&call_builtin);
326 __ push(a0);
327 __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
328 }
329
330
331 void FastNewClosureStub::Generate(MacroAssembler* masm) { 324 void FastNewClosureStub::Generate(MacroAssembler* masm) {
332 // Create a new closure from the given function info in new 325 // Create a new closure from the given function info in new
333 // space. Set the context to the current context in cp. 326 // space. Set the context to the current context in cp.
334 Counters* counters = masm->isolate()->counters(); 327 Counters* counters = masm->isolate()->counters();
335 328
336 Label gc; 329 Label gc;
337 330
338 // Pop the function info from the stack. 331 // Pop the function info from the stack.
339 __ pop(a3); 332 __ pop(a3);
340 333
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE)); 1200 __ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE));
1208 1201
1209 __ GetObjectType(rhs, a3, a3); 1202 __ GetObjectType(rhs, a3, a3);
1210 __ Branch(&return_not_equal, greater, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); 1203 __ Branch(&return_not_equal, greater, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
1211 1204
1212 // Check for oddballs: true, false, null, undefined. 1205 // Check for oddballs: true, false, null, undefined.
1213 __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE)); 1206 __ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE));
1214 1207
1215 // Now that we have the types we might as well check for 1208 // Now that we have the types we might as well check for
1216 // internalized-internalized. 1209 // internalized-internalized.
1217 Label not_internalized; 1210 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
1218 STATIC_ASSERT(kInternalizedTag != 0); 1211 __ Or(a2, a2, Operand(a3));
1219 __ And(t2, a2, Operand(kIsNotStringMask | kIsInternalizedMask)); 1212 __ And(at, a2, Operand(kIsNotStringMask | kIsNotInternalizedMask));
1220 __ Branch(&not_internalized, ne, t2, 1213 __ Branch(&return_not_equal, eq, at, Operand(zero_reg));
1221 Operand(kInternalizedTag | kStringTag));
1222
1223 __ And(a3, a3, Operand(kIsNotStringMask | kIsInternalizedMask));
1224 __ Branch(&return_not_equal, eq, a3,
1225 Operand(kInternalizedTag | kStringTag));
1226
1227 __ bind(&not_internalized);
1228 } 1214 }
1229 1215
1230 1216
1231 static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm, 1217 static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm,
1232 Register lhs, 1218 Register lhs,
1233 Register rhs, 1219 Register rhs,
1234 Label* both_loaded_as_doubles, 1220 Label* both_loaded_as_doubles,
1235 Label* not_heap_numbers, 1221 Label* not_heap_numbers,
1236 Label* slow) { 1222 Label* slow) {
1237 __ GetObjectType(lhs, a3, a2); 1223 __ GetObjectType(lhs, a3, a2);
(...skipping 15 matching lines...) Expand all
1253 static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm, 1239 static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm,
1254 Register lhs, 1240 Register lhs,
1255 Register rhs, 1241 Register rhs,
1256 Label* possible_strings, 1242 Label* possible_strings,
1257 Label* not_both_strings) { 1243 Label* not_both_strings) {
1258 ASSERT((lhs.is(a0) && rhs.is(a1)) || 1244 ASSERT((lhs.is(a0) && rhs.is(a1)) ||
1259 (lhs.is(a1) && rhs.is(a0))); 1245 (lhs.is(a1) && rhs.is(a0)));
1260 1246
1261 // a2 is object type of rhs. 1247 // a2 is object type of rhs.
1262 Label object_test; 1248 Label object_test;
1263 STATIC_ASSERT(kInternalizedTag != 0); 1249 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
1264 __ And(at, a2, Operand(kIsNotStringMask)); 1250 __ And(at, a2, Operand(kIsNotStringMask));
1265 __ Branch(&object_test, ne, at, Operand(zero_reg)); 1251 __ Branch(&object_test, ne, at, Operand(zero_reg));
1266 __ And(at, a2, Operand(kIsInternalizedMask)); 1252 __ And(at, a2, Operand(kIsNotInternalizedMask));
1267 __ Branch(possible_strings, eq, at, Operand(zero_reg)); 1253 __ Branch(possible_strings, ne, at, Operand(zero_reg));
1268 __ GetObjectType(rhs, a3, a3); 1254 __ GetObjectType(rhs, a3, a3);
1269 __ Branch(not_both_strings, ge, a3, Operand(FIRST_NONSTRING_TYPE)); 1255 __ Branch(not_both_strings, ge, a3, Operand(FIRST_NONSTRING_TYPE));
1270 __ And(at, a3, Operand(kIsInternalizedMask)); 1256 __ And(at, a3, Operand(kIsNotInternalizedMask));
1271 __ Branch(possible_strings, eq, at, Operand(zero_reg)); 1257 __ Branch(possible_strings, ne, at, Operand(zero_reg));
1272 1258
1273 // Both are internalized strings. We already checked they weren't the same 1259 // Both are internalized strings. We already checked they weren't the same
1274 // pointer so they are not equal. 1260 // pointer so they are not equal.
1275 __ Ret(USE_DELAY_SLOT); 1261 __ Ret(USE_DELAY_SLOT);
1276 __ li(v0, Operand(1)); // Non-zero indicates not equal. 1262 __ li(v0, Operand(1)); // Non-zero indicates not equal.
1277 1263
1278 __ bind(&object_test); 1264 __ bind(&object_test);
1279 __ Branch(not_both_strings, lt, a2, Operand(FIRST_SPEC_OBJECT_TYPE)); 1265 __ Branch(not_both_strings, lt, a2, Operand(FIRST_SPEC_OBJECT_TYPE));
1280 __ GetObjectType(rhs, a2, a3); 1266 __ GetObjectType(rhs, a2, a3);
1281 __ Branch(not_both_strings, lt, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); 1267 __ Branch(not_both_strings, lt, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
(...skipping 10 matching lines...) Expand all
1292 __ xori(v0, a0, 1 << Map::kIsUndetectable); 1278 __ xori(v0, a0, 1 << Map::kIsUndetectable);
1293 } 1279 }
1294 1280
1295 1281
1296 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, 1282 void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm,
1297 Register object, 1283 Register object,
1298 Register result, 1284 Register result,
1299 Register scratch1, 1285 Register scratch1,
1300 Register scratch2, 1286 Register scratch2,
1301 Register scratch3, 1287 Register scratch3,
1302 bool object_is_smi,
1303 Label* not_found) { 1288 Label* not_found) {
1304 // Use of registers. Register result is used as a temporary. 1289 // Use of registers. Register result is used as a temporary.
1305 Register number_string_cache = result; 1290 Register number_string_cache = result;
1306 Register mask = scratch3; 1291 Register mask = scratch3;
1307 1292
1308 // Load the number string cache. 1293 // Load the number string cache.
1309 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); 1294 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
1310 1295
1311 // Make the hash mask from the length of the number string cache. It 1296 // Make the hash mask from the length of the number string cache. It
1312 // contains two elements (number and string) for each cache entry. 1297 // contains two elements (number and string) for each cache entry.
1313 __ lw(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset)); 1298 __ lw(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset));
1314 // Divide length by two (length is a smi). 1299 // Divide length by two (length is a smi).
1315 __ sra(mask, mask, kSmiTagSize + 1); 1300 __ sra(mask, mask, kSmiTagSize + 1);
1316 __ Addu(mask, mask, -1); // Make mask. 1301 __ Addu(mask, mask, -1); // Make mask.
1317 1302
1318 // Calculate the entry in the number string cache. The hash value in the 1303 // Calculate the entry in the number string cache. The hash value in the
1319 // number string cache for smis is just the smi value, and the hash for 1304 // number string cache for smis is just the smi value, and the hash for
1320 // doubles is the xor of the upper and lower words. See 1305 // doubles is the xor of the upper and lower words. See
1321 // Heap::GetNumberStringCache. 1306 // Heap::GetNumberStringCache.
1322 Isolate* isolate = masm->isolate(); 1307 Isolate* isolate = masm->isolate();
1323 Label is_smi; 1308 Label is_smi;
1324 Label load_result_from_cache; 1309 Label load_result_from_cache;
1325 if (!object_is_smi) { 1310 __ JumpIfSmi(object, &is_smi);
1326 __ JumpIfSmi(object, &is_smi); 1311 __ CheckMap(object,
1327 __ CheckMap(object, 1312 scratch1,
1328 scratch1, 1313 Heap::kHeapNumberMapRootIndex,
1329 Heap::kHeapNumberMapRootIndex, 1314 not_found,
1330 not_found, 1315 DONT_DO_SMI_CHECK);
1331 DONT_DO_SMI_CHECK);
1332 1316
1333 STATIC_ASSERT(8 == kDoubleSize); 1317 STATIC_ASSERT(8 == kDoubleSize);
1334 __ Addu(scratch1, 1318 __ Addu(scratch1,
1335 object, 1319 object,
1336 Operand(HeapNumber::kValueOffset - kHeapObjectTag)); 1320 Operand(HeapNumber::kValueOffset - kHeapObjectTag));
1337 __ lw(scratch2, MemOperand(scratch1, kPointerSize)); 1321 __ lw(scratch2, MemOperand(scratch1, kPointerSize));
1338 __ lw(scratch1, MemOperand(scratch1, 0)); 1322 __ lw(scratch1, MemOperand(scratch1, 0));
1339 __ Xor(scratch1, scratch1, Operand(scratch2)); 1323 __ Xor(scratch1, scratch1, Operand(scratch2));
1340 __ And(scratch1, scratch1, Operand(mask)); 1324 __ And(scratch1, scratch1, Operand(mask));
1341 1325
1342 // Calculate address of entry in string cache: each entry consists 1326 // Calculate address of entry in string cache: each entry consists
1343 // of two pointer sized fields. 1327 // of two pointer sized fields.
1344 __ sll(scratch1, scratch1, kPointerSizeLog2 + 1); 1328 __ sll(scratch1, scratch1, kPointerSizeLog2 + 1);
1345 __ Addu(scratch1, number_string_cache, scratch1); 1329 __ Addu(scratch1, number_string_cache, scratch1);
1346 1330
1347 Register probe = mask; 1331 Register probe = mask;
1348 __ lw(probe, 1332 __ lw(probe,
1349 FieldMemOperand(scratch1, FixedArray::kHeaderSize)); 1333 FieldMemOperand(scratch1, FixedArray::kHeaderSize));
1350 __ JumpIfSmi(probe, not_found); 1334 __ JumpIfSmi(probe, not_found);
1351 __ ldc1(f12, FieldMemOperand(object, HeapNumber::kValueOffset)); 1335 __ ldc1(f12, FieldMemOperand(object, HeapNumber::kValueOffset));
1352 __ ldc1(f14, FieldMemOperand(probe, HeapNumber::kValueOffset)); 1336 __ ldc1(f14, FieldMemOperand(probe, HeapNumber::kValueOffset));
1353 __ BranchF(&load_result_from_cache, NULL, eq, f12, f14); 1337 __ BranchF(&load_result_from_cache, NULL, eq, f12, f14);
1354 __ Branch(not_found); 1338 __ Branch(not_found);
1355 }
1356 1339
1357 __ bind(&is_smi); 1340 __ bind(&is_smi);
1358 Register scratch = scratch1; 1341 Register scratch = scratch1;
1359 __ sra(scratch, object, 1); // Shift away the tag. 1342 __ sra(scratch, object, 1); // Shift away the tag.
1360 __ And(scratch, mask, Operand(scratch)); 1343 __ And(scratch, mask, Operand(scratch));
1361 1344
1362 // Calculate address of entry in string cache: each entry consists 1345 // Calculate address of entry in string cache: each entry consists
1363 // of two pointer sized fields. 1346 // of two pointer sized fields.
1364 __ sll(scratch, scratch, kPointerSizeLog2 + 1); 1347 __ sll(scratch, scratch, kPointerSizeLog2 + 1);
1365 __ Addu(scratch, number_string_cache, scratch); 1348 __ Addu(scratch, number_string_cache, scratch);
1366 1349
1367 // Check if the entry is the smi we are looking for. 1350 // Check if the entry is the smi we are looking for.
1368 Register probe = mask;
1369 __ lw(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 1351 __ lw(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize));
1370 __ Branch(not_found, ne, object, Operand(probe)); 1352 __ Branch(not_found, ne, object, Operand(probe));
1371 1353
1372 // Get the result from the cache. 1354 // Get the result from the cache.
1373 __ bind(&load_result_from_cache); 1355 __ bind(&load_result_from_cache);
1374 __ lw(result, 1356 __ lw(result,
1375 FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize)); 1357 FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize));
1376 1358
1377 __ IncrementCounter(isolate->counters()->number_to_string_native(), 1359 __ IncrementCounter(isolate->counters()->number_to_string_native(),
1378 1, 1360 1,
1379 scratch1, 1361 scratch1,
1380 scratch2); 1362 scratch2);
1381 } 1363 }
1382 1364
1383 1365
1384 void NumberToStringStub::Generate(MacroAssembler* masm) { 1366 void NumberToStringStub::Generate(MacroAssembler* masm) {
1385 Label runtime; 1367 Label runtime;
1386 1368
1387 __ lw(a1, MemOperand(sp, 0)); 1369 __ lw(a1, MemOperand(sp, 0));
1388 1370
1389 // Generate code to lookup number in the number string cache. 1371 // Generate code to lookup number in the number string cache.
1390 GenerateLookupNumberStringCache(masm, a1, v0, a2, a3, t0, false, &runtime); 1372 GenerateLookupNumberStringCache(masm, a1, v0, a2, a3, t0, &runtime);
1391 __ DropAndRet(1); 1373 __ DropAndRet(1);
1392 1374
1393 __ bind(&runtime); 1375 __ bind(&runtime);
1394 // Handle number to string in the runtime system if not found in the cache. 1376 // Handle number to string in the runtime system if not found in the cache.
1395 __ TailCallRuntime(Runtime::kNumberToString, 1, 1); 1377 __ TailCallRuntime(Runtime::kNumberToString, 1, 1);
1396 } 1378 }
1397 1379
1398 1380
1399 static void ICCompareStub_CheckInputType(MacroAssembler* masm, 1381 static void ICCompareStub_CheckInputType(MacroAssembler* masm,
1400 Register input, 1382 Register input,
(...skipping 725 matching lines...) Expand 10 before | Expand all | Expand 10 after
2126 // Test if left operand is a string. 2108 // Test if left operand is a string.
2127 __ JumpIfSmi(left, &call_runtime); 2109 __ JumpIfSmi(left, &call_runtime);
2128 __ GetObjectType(left, a2, a2); 2110 __ GetObjectType(left, a2, a2);
2129 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE)); 2111 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE));
2130 2112
2131 // Test if right operand is a string. 2113 // Test if right operand is a string.
2132 __ JumpIfSmi(right, &call_runtime); 2114 __ JumpIfSmi(right, &call_runtime);
2133 __ GetObjectType(right, a2, a2); 2115 __ GetObjectType(right, a2, a2);
2134 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE)); 2116 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE));
2135 2117
2136 StringAddStub string_add_stub((StringAddFlags) 2118 StringAddStub string_add_stub(
2137 (ERECT_FRAME | NO_STRING_CHECK_IN_STUB)); 2119 (StringAddFlags)(STRING_ADD_CHECK_NONE | STRING_ADD_ERECT_FRAME));
2138 GenerateRegisterArgsPush(masm); 2120 GenerateRegisterArgsPush(masm);
2139 __ TailCallStub(&string_add_stub); 2121 __ TailCallStub(&string_add_stub);
2140 2122
2141 __ bind(&call_runtime); 2123 __ bind(&call_runtime);
2142 GenerateTypeTransition(masm); 2124 GenerateTypeTransition(masm);
2143 } 2125 }
2144 2126
2145 2127
2146 void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { 2128 void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
2147 ASSERT(Max(left_type_, right_type_) == BinaryOpIC::INT32); 2129 ASSERT(Max(left_type_, right_type_) == BinaryOpIC::INT32);
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
2544 Label left_not_string, call_runtime; 2526 Label left_not_string, call_runtime;
2545 2527
2546 Register left = a1; 2528 Register left = a1;
2547 Register right = a0; 2529 Register right = a0;
2548 2530
2549 // Check if left argument is a string. 2531 // Check if left argument is a string.
2550 __ JumpIfSmi(left, &left_not_string); 2532 __ JumpIfSmi(left, &left_not_string);
2551 __ GetObjectType(left, a2, a2); 2533 __ GetObjectType(left, a2, a2);
2552 __ Branch(&left_not_string, ge, a2, Operand(FIRST_NONSTRING_TYPE)); 2534 __ Branch(&left_not_string, ge, a2, Operand(FIRST_NONSTRING_TYPE));
2553 2535
2554 StringAddStub string_add_left_stub((StringAddFlags) 2536 StringAddStub string_add_left_stub(
2555 (ERECT_FRAME | NO_STRING_CHECK_LEFT_IN_STUB)); 2537 (StringAddFlags)(STRING_ADD_CHECK_RIGHT | STRING_ADD_ERECT_FRAME));
2556 GenerateRegisterArgsPush(masm); 2538 GenerateRegisterArgsPush(masm);
2557 __ TailCallStub(&string_add_left_stub); 2539 __ TailCallStub(&string_add_left_stub);
2558 2540
2559 // Left operand is not a string, test right. 2541 // Left operand is not a string, test right.
2560 __ bind(&left_not_string); 2542 __ bind(&left_not_string);
2561 __ JumpIfSmi(right, &call_runtime); 2543 __ JumpIfSmi(right, &call_runtime);
2562 __ GetObjectType(right, a2, a2); 2544 __ GetObjectType(right, a2, a2);
2563 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE)); 2545 __ Branch(&call_runtime, ge, a2, Operand(FIRST_NONSTRING_TYPE));
2564 2546
2565 StringAddStub string_add_right_stub((StringAddFlags) 2547 StringAddStub string_add_right_stub(
2566 (ERECT_FRAME | NO_STRING_CHECK_RIGHT_IN_STUB)); 2548 (StringAddFlags)(STRING_ADD_CHECK_LEFT | STRING_ADD_ERECT_FRAME));
2567 GenerateRegisterArgsPush(masm); 2549 GenerateRegisterArgsPush(masm);
2568 __ TailCallStub(&string_add_right_stub); 2550 __ TailCallStub(&string_add_right_stub);
2569 2551
2570 // At least one argument is not a string. 2552 // At least one argument is not a string.
2571 __ bind(&call_runtime); 2553 __ bind(&call_runtime);
2572 } 2554 }
2573 2555
2574 2556
2575 void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm, 2557 void BinaryOpStub_GenerateHeapResultAllocation(MacroAssembler* masm,
2576 Register result, 2558 Register result,
(...skipping 3281 matching lines...) Expand 10 before | Expand all | Expand 10 after
5858 5840
5859 // Stack on entry: 5841 // Stack on entry:
5860 // sp[0]: second argument (right). 5842 // sp[0]: second argument (right).
5861 // sp[4]: first argument (left). 5843 // sp[4]: first argument (left).
5862 5844
5863 // Load the two arguments. 5845 // Load the two arguments.
5864 __ lw(a0, MemOperand(sp, 1 * kPointerSize)); // First argument. 5846 __ lw(a0, MemOperand(sp, 1 * kPointerSize)); // First argument.
5865 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); // Second argument. 5847 __ lw(a1, MemOperand(sp, 0 * kPointerSize)); // Second argument.
5866 5848
5867 // Make sure that both arguments are strings if not known in advance. 5849 // Make sure that both arguments are strings if not known in advance.
5868 if ((flags_ & NO_STRING_ADD_FLAGS) != 0) { 5850 // Otherwise, at least one of the arguments is definitely a string,
5851 // and we convert the one that is not known to be a string.
5852 if ((flags_ & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
5853 ASSERT((flags_ & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT);
5854 ASSERT((flags_ & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT);
5869 __ JumpIfEitherSmi(a0, a1, &call_runtime); 5855 __ JumpIfEitherSmi(a0, a1, &call_runtime);
5870 // Load instance types. 5856 // Load instance types.
5871 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); 5857 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset));
5872 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); 5858 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
5873 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); 5859 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
5874 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); 5860 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset));
5875 STATIC_ASSERT(kStringTag == 0); 5861 STATIC_ASSERT(kStringTag == 0);
5876 // If either is not a string, go to runtime. 5862 // If either is not a string, go to runtime.
5877 __ Or(t4, t0, Operand(t1)); 5863 __ Or(t4, t0, Operand(t1));
5878 __ And(t4, t4, Operand(kIsNotStringMask)); 5864 __ And(t4, t4, Operand(kIsNotStringMask));
5879 __ Branch(&call_runtime, ne, t4, Operand(zero_reg)); 5865 __ Branch(&call_runtime, ne, t4, Operand(zero_reg));
5880 } else { 5866 } else if ((flags_ & STRING_ADD_CHECK_LEFT) == STRING_ADD_CHECK_LEFT) {
5881 // Here at least one of the arguments is definitely a string. 5867 ASSERT((flags_ & STRING_ADD_CHECK_RIGHT) == 0);
5882 // We convert the one that is not known to be a string. 5868 GenerateConvertArgument(
5883 if ((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) == 0) { 5869 masm, 1 * kPointerSize, a0, a2, a3, t0, t1, &call_builtin);
5884 ASSERT((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) != 0); 5870 builtin_id = Builtins::STRING_ADD_RIGHT;
5885 GenerateConvertArgument( 5871 } else if ((flags_ & STRING_ADD_CHECK_RIGHT) == STRING_ADD_CHECK_RIGHT) {
5886 masm, 1 * kPointerSize, a0, a2, a3, t0, t1, &call_builtin); 5872 ASSERT((flags_ & STRING_ADD_CHECK_LEFT) == 0);
5887 builtin_id = Builtins::STRING_ADD_RIGHT; 5873 GenerateConvertArgument(
5888 } else if ((flags_ & NO_STRING_CHECK_RIGHT_IN_STUB) == 0) { 5874 masm, 0 * kPointerSize, a1, a2, a3, t0, t1, &call_builtin);
5889 ASSERT((flags_ & NO_STRING_CHECK_LEFT_IN_STUB) != 0); 5875 builtin_id = Builtins::STRING_ADD_LEFT;
5890 GenerateConvertArgument(
5891 masm, 0 * kPointerSize, a1, a2, a3, t0, t1, &call_builtin);
5892 builtin_id = Builtins::STRING_ADD_LEFT;
5893 }
5894 } 5876 }
5895 5877
5896 // Both arguments are strings. 5878 // Both arguments are strings.
5897 // a0: first string 5879 // a0: first string
5898 // a1: second string 5880 // a1: second string
5899 // t0: first string instance type (if flags_ == NO_STRING_ADD_FLAGS) 5881 // t0: first string instance type (if flags_ == NO_STRING_ADD_FLAGS)
5900 // t1: second string instance type (if flags_ == NO_STRING_ADD_FLAGS) 5882 // t1: second string instance type (if flags_ == NO_STRING_ADD_FLAGS)
5901 { 5883 {
5902 Label strings_not_empty; 5884 Label strings_not_empty;
5903 // Check if either of the strings are empty. In that case return the other. 5885 // Check if either of the strings are empty. In that case return the other.
(...skipping 30 matching lines...) Expand all
5934 // Look at the length of the result of adding the two strings. 5916 // Look at the length of the result of adding the two strings.
5935 Label string_add_flat_result, longer_than_two; 5917 Label string_add_flat_result, longer_than_two;
5936 // Adding two lengths can't overflow. 5918 // Adding two lengths can't overflow.
5937 STATIC_ASSERT(String::kMaxLength < String::kMaxLength * 2); 5919 STATIC_ASSERT(String::kMaxLength < String::kMaxLength * 2);
5938 __ Addu(t2, a2, Operand(a3)); 5920 __ Addu(t2, a2, Operand(a3));
5939 // Use the string table when adding two one character strings, as it 5921 // Use the string table when adding two one character strings, as it
5940 // helps later optimizations to return a string here. 5922 // helps later optimizations to return a string here.
5941 __ Branch(&longer_than_two, ne, t2, Operand(2)); 5923 __ Branch(&longer_than_two, ne, t2, Operand(2));
5942 5924
5943 // Check that both strings are non-external ASCII strings. 5925 // Check that both strings are non-external ASCII strings.
5944 if (flags_ != NO_STRING_ADD_FLAGS) { 5926 if ((flags_ & STRING_ADD_CHECK_BOTH) != STRING_ADD_CHECK_BOTH) {
5945 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); 5927 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset));
5946 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); 5928 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
5947 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); 5929 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
5948 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); 5930 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset));
5949 } 5931 }
5950 __ JumpIfBothInstanceTypesAreNotSequentialAscii(t0, t1, t2, t3, 5932 __ JumpIfBothInstanceTypesAreNotSequentialAscii(t0, t1, t2, t3,
5951 &call_runtime); 5933 &call_runtime);
5952 5934
5953 // Get the two characters forming the sub string. 5935 // Get the two characters forming the sub string.
5954 __ lbu(a2, FieldMemOperand(a0, SeqOneByteString::kHeaderSize)); 5936 __ lbu(a2, FieldMemOperand(a0, SeqOneByteString::kHeaderSize));
(...skipping 23 matching lines...) Expand all
5978 // Check if resulting string will be flat. 5960 // Check if resulting string will be flat.
5979 __ Branch(&string_add_flat_result, lt, t2, Operand(ConsString::kMinLength)); 5961 __ Branch(&string_add_flat_result, lt, t2, Operand(ConsString::kMinLength));
5980 // Handle exceptionally long strings in the runtime system. 5962 // Handle exceptionally long strings in the runtime system.
5981 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0); 5963 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0);
5982 ASSERT(IsPowerOf2(String::kMaxLength + 1)); 5964 ASSERT(IsPowerOf2(String::kMaxLength + 1));
5983 // kMaxLength + 1 is representable as shifted literal, kMaxLength is not. 5965 // kMaxLength + 1 is representable as shifted literal, kMaxLength is not.
5984 __ Branch(&call_runtime, hs, t2, Operand(String::kMaxLength + 1)); 5966 __ Branch(&call_runtime, hs, t2, Operand(String::kMaxLength + 1));
5985 5967
5986 // If result is not supposed to be flat, allocate a cons string object. 5968 // If result is not supposed to be flat, allocate a cons string object.
5987 // If both strings are ASCII the result is an ASCII cons string. 5969 // If both strings are ASCII the result is an ASCII cons string.
5988 if (flags_ != NO_STRING_ADD_FLAGS) { 5970 if ((flags_ & STRING_ADD_CHECK_BOTH) != STRING_ADD_CHECK_BOTH) {
5989 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); 5971 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset));
5990 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); 5972 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
5991 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); 5973 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
5992 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); 5974 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset));
5993 } 5975 }
5994 Label non_ascii, allocated, ascii_data; 5976 Label non_ascii, allocated, ascii_data;
5995 STATIC_ASSERT(kTwoByteStringTag == 0); 5977 STATIC_ASSERT(kTwoByteStringTag == 0);
5996 // Branch to non_ascii if either string-encoding field is zero (non-ASCII). 5978 // Branch to non_ascii if either string-encoding field is zero (non-ASCII).
5997 __ And(t4, t0, Operand(t1)); 5979 __ And(t4, t0, Operand(t1));
5998 __ And(t4, t4, Operand(kStringEncodingMask)); 5980 __ And(t4, t4, Operand(kStringEncodingMask));
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
6061 // Locate the first characters' locations. 6043 // Locate the first characters' locations.
6062 // a0: first string 6044 // a0: first string
6063 // a1: second string 6045 // a1: second string
6064 // a2: length of first string 6046 // a2: length of first string
6065 // a3: length of second string 6047 // a3: length of second string
6066 // t0: first string instance type (if flags_ == NO_STRING_ADD_FLAGS) 6048 // t0: first string instance type (if flags_ == NO_STRING_ADD_FLAGS)
6067 // t1: second string instance type (if flags_ == NO_STRING_ADD_FLAGS) 6049 // t1: second string instance type (if flags_ == NO_STRING_ADD_FLAGS)
6068 // t2: sum of lengths. 6050 // t2: sum of lengths.
6069 Label first_prepared, second_prepared; 6051 Label first_prepared, second_prepared;
6070 __ bind(&string_add_flat_result); 6052 __ bind(&string_add_flat_result);
6071 if (flags_ != NO_STRING_ADD_FLAGS) { 6053 if ((flags_ & STRING_ADD_CHECK_BOTH) != STRING_ADD_CHECK_BOTH) {
6072 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset)); 6054 __ lw(t0, FieldMemOperand(a0, HeapObject::kMapOffset));
6073 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset)); 6055 __ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
6074 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset)); 6056 __ lbu(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
6075 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset)); 6057 __ lbu(t1, FieldMemOperand(t1, Map::kInstanceTypeOffset));
6076 } 6058 }
6077 // Check whether both strings have same encoding 6059 // Check whether both strings have same encoding
6078 __ Xor(t3, t0, Operand(t1)); 6060 __ Xor(t3, t0, Operand(t1));
6079 __ And(t3, t3, Operand(kStringEncodingMask)); 6061 __ And(t3, t3, Operand(kStringEncodingMask));
6080 __ Branch(&call_runtime, ne, t3, Operand(zero_reg)); 6062 __ Branch(&call_runtime, ne, t3, Operand(zero_reg));
6081 6063
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
6147 // t2: first character of result. 6129 // t2: first character of result.
6148 StringHelper::GenerateCopyCharacters(masm, t2, t3, a2, t0, false); 6130 StringHelper::GenerateCopyCharacters(masm, t2, t3, a2, t0, false);
6149 // t2: next character of result. 6131 // t2: next character of result.
6150 StringHelper::GenerateCopyCharacters(masm, t2, a1, a3, t0, false); 6132 StringHelper::GenerateCopyCharacters(masm, t2, a1, a3, t0, false);
6151 6133
6152 __ IncrementCounter(counters->string_add_native(), 1, a2, a3); 6134 __ IncrementCounter(counters->string_add_native(), 1, a2, a3);
6153 __ DropAndRet(2); 6135 __ DropAndRet(2);
6154 6136
6155 // Just jump to runtime to add the two strings. 6137 // Just jump to runtime to add the two strings.
6156 __ bind(&call_runtime); 6138 __ bind(&call_runtime);
6157 if ((flags_ & ERECT_FRAME) != 0) { 6139 if ((flags_ & STRING_ADD_ERECT_FRAME) != 0) {
6158 GenerateRegisterArgsPop(masm); 6140 GenerateRegisterArgsPop(masm);
6159 // Build a frame. 6141 // Build a frame.
6160 { 6142 {
6161 FrameScope scope(masm, StackFrame::INTERNAL); 6143 FrameScope scope(masm, StackFrame::INTERNAL);
6162 GenerateRegisterArgsPush(masm); 6144 GenerateRegisterArgsPush(masm);
6163 __ CallRuntime(Runtime::kStringAdd, 2); 6145 __ CallRuntime(Runtime::kStringAdd, 2);
6164 } 6146 }
6165 __ Ret(); 6147 __ Ret();
6166 } else { 6148 } else {
6167 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 6149 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
6168 } 6150 }
6169 6151
6170 if (call_builtin.is_linked()) { 6152 if (call_builtin.is_linked()) {
6171 __ bind(&call_builtin); 6153 __ bind(&call_builtin);
6172 if ((flags_ & ERECT_FRAME) != 0) { 6154 if ((flags_ & STRING_ADD_ERECT_FRAME) != 0) {
6173 GenerateRegisterArgsPop(masm); 6155 GenerateRegisterArgsPop(masm);
6174 // Build a frame. 6156 // Build a frame.
6175 { 6157 {
6176 FrameScope scope(masm, StackFrame::INTERNAL); 6158 FrameScope scope(masm, StackFrame::INTERNAL);
6177 GenerateRegisterArgsPush(masm); 6159 GenerateRegisterArgsPush(masm);
6178 __ InvokeBuiltin(builtin_id, CALL_FUNCTION); 6160 __ InvokeBuiltin(builtin_id, CALL_FUNCTION);
6179 } 6161 }
6180 __ Ret(); 6162 __ Ret();
6181 } else { 6163 } else {
6182 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION); 6164 __ InvokeBuiltin(builtin_id, JUMP_FUNCTION);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
6214 // Check the number to string cache. 6196 // Check the number to string cache.
6215 Label not_cached; 6197 Label not_cached;
6216 __ bind(&not_string); 6198 __ bind(&not_string);
6217 // Puts the cached result into scratch1. 6199 // Puts the cached result into scratch1.
6218 NumberToStringStub::GenerateLookupNumberStringCache(masm, 6200 NumberToStringStub::GenerateLookupNumberStringCache(masm,
6219 arg, 6201 arg,
6220 scratch1, 6202 scratch1,
6221 scratch2, 6203 scratch2,
6222 scratch3, 6204 scratch3,
6223 scratch4, 6205 scratch4,
6224 false,
6225 &not_cached); 6206 &not_cached);
6226 __ mov(arg, scratch1); 6207 __ mov(arg, scratch1);
6227 __ sw(arg, MemOperand(sp, stack_offset)); 6208 __ sw(arg, MemOperand(sp, stack_offset));
6228 __ jmp(&done); 6209 __ jmp(&done);
6229 6210
6230 // Check if the argument is a safe string wrapper. 6211 // Check if the argument is a safe string wrapper.
6231 __ bind(&not_cached); 6212 __ bind(&not_cached);
6232 __ JumpIfSmi(arg, slow); 6213 __ JumpIfSmi(arg, slow);
6233 __ GetObjectType(arg, scratch1, scratch2); // map -> scratch1. 6214 __ GetObjectType(arg, scratch1, scratch2); // map -> scratch1.
6234 __ Branch(slow, ne, scratch2, Operand(JS_VALUE_TYPE)); 6215 __ Branch(slow, ne, scratch2, Operand(JS_VALUE_TYPE));
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
6370 Register tmp2 = a3; 6351 Register tmp2 = a3;
6371 6352
6372 // Check that both operands are heap objects. 6353 // Check that both operands are heap objects.
6373 __ JumpIfEitherSmi(left, right, &miss); 6354 __ JumpIfEitherSmi(left, right, &miss);
6374 6355
6375 // Check that both operands are internalized strings. 6356 // Check that both operands are internalized strings.
6376 __ lw(tmp1, FieldMemOperand(left, HeapObject::kMapOffset)); 6357 __ lw(tmp1, FieldMemOperand(left, HeapObject::kMapOffset));
6377 __ lw(tmp2, FieldMemOperand(right, HeapObject::kMapOffset)); 6358 __ lw(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
6378 __ lbu(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); 6359 __ lbu(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset));
6379 __ lbu(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); 6360 __ lbu(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset));
6380 STATIC_ASSERT(kInternalizedTag != 0); 6361 STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
6381 6362 __ Or(tmp1, tmp1, Operand(tmp2));
6382 __ And(tmp1, tmp1, Operand(kIsNotStringMask | kIsInternalizedMask)); 6363 __ And(at, tmp1, Operand(kIsNotStringMask | kIsNotInternalizedMask));
6383 __ Branch(&miss, ne, tmp1, Operand(kInternalizedTag | kStringTag)); 6364 __ Branch(&miss, ne, at, Operand(zero_reg));
6384
6385 __ And(tmp2, tmp2, Operand(kIsNotStringMask | kIsInternalizedMask));
6386 __ Branch(&miss, ne, tmp2, Operand(kInternalizedTag | kStringTag));
6387 6365
6388 // Make sure a0 is non-zero. At this point input operands are 6366 // Make sure a0 is non-zero. At this point input operands are
6389 // guaranteed to be non-zero. 6367 // guaranteed to be non-zero.
6390 ASSERT(right.is(a0)); 6368 ASSERT(right.is(a0));
6391 STATIC_ASSERT(EQUAL == 0); 6369 STATIC_ASSERT(EQUAL == 0);
6392 STATIC_ASSERT(kSmiTag == 0); 6370 STATIC_ASSERT(kSmiTag == 0);
6393 __ mov(v0, right); 6371 __ mov(v0, right);
6394 // Internalized strings are compared by identity. 6372 // Internalized strings are compared by identity.
6395 __ Ret(ne, left, Operand(right)); 6373 __ Ret(ne, left, Operand(right));
6396 ASSERT(is_int16(EQUAL)); 6374 ASSERT(is_int16(EQUAL));
(...skipping 14 matching lines...) Expand all
6411 Register left = a1; 6389 Register left = a1;
6412 Register right = a0; 6390 Register right = a0;
6413 Register tmp1 = a2; 6391 Register tmp1 = a2;
6414 Register tmp2 = a3; 6392 Register tmp2 = a3;
6415 6393
6416 // Check that both operands are heap objects. 6394 // Check that both operands are heap objects.
6417 __ JumpIfEitherSmi(left, right, &miss); 6395 __ JumpIfEitherSmi(left, right, &miss);
6418 6396
6419 // Check that both operands are unique names. This leaves the instance 6397 // Check that both operands are unique names. This leaves the instance
6420 // types loaded in tmp1 and tmp2. 6398 // types loaded in tmp1 and tmp2.
6421 STATIC_ASSERT(kInternalizedTag != 0);
6422 __ lw(tmp1, FieldMemOperand(left, HeapObject::kMapOffset)); 6399 __ lw(tmp1, FieldMemOperand(left, HeapObject::kMapOffset));
6423 __ lw(tmp2, FieldMemOperand(right, HeapObject::kMapOffset)); 6400 __ lw(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
6424 __ lbu(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset)); 6401 __ lbu(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset));
6425 __ lbu(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset)); 6402 __ lbu(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset));
6426 6403
6427 __ JumpIfNotUniqueName(tmp1, &miss); 6404 __ JumpIfNotUniqueName(tmp1, &miss);
6428 __ JumpIfNotUniqueName(tmp2, &miss); 6405 __ JumpIfNotUniqueName(tmp2, &miss);
6429 6406
6430 // Use a0 as result 6407 // Use a0 as result
6431 __ mov(v0, a0); 6408 __ mov(v0, a0);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
6485 __ mov(v0, zero_reg); // In the delay slot. 6462 __ mov(v0, zero_reg); // In the delay slot.
6486 __ bind(&left_ne_right); 6463 __ bind(&left_ne_right);
6487 6464
6488 // Handle not identical strings. 6465 // Handle not identical strings.
6489 6466
6490 // Check that both strings are internalized strings. If they are, we're done 6467 // Check that both strings are internalized strings. If they are, we're done
6491 // because we already know they are not identical. We know they are both 6468 // because we already know they are not identical. We know they are both
6492 // strings. 6469 // strings.
6493 if (equality) { 6470 if (equality) {
6494 ASSERT(GetCondition() == eq); 6471 ASSERT(GetCondition() == eq);
6495 STATIC_ASSERT(kInternalizedTag != 0); 6472 STATIC_ASSERT(kInternalizedTag == 0);
6496 __ And(tmp3, tmp1, Operand(tmp2)); 6473 __ Or(tmp3, tmp1, Operand(tmp2));
6497 __ And(tmp5, tmp3, Operand(kIsInternalizedMask)); 6474 __ And(tmp5, tmp3, Operand(kIsNotInternalizedMask));
6498 Label is_symbol; 6475 Label is_symbol;
6499 __ Branch(&is_symbol, eq, tmp5, Operand(zero_reg)); 6476 __ Branch(&is_symbol, ne, tmp5, Operand(zero_reg));
6500 // Make sure a0 is non-zero. At this point input operands are 6477 // Make sure a0 is non-zero. At this point input operands are
6501 // guaranteed to be non-zero. 6478 // guaranteed to be non-zero.
6502 ASSERT(right.is(a0)); 6479 ASSERT(right.is(a0));
6503 __ Ret(USE_DELAY_SLOT); 6480 __ Ret(USE_DELAY_SLOT);
6504 __ mov(v0, a0); // In the delay slot. 6481 __ mov(v0, a0); // In the delay slot.
6505 __ bind(&is_symbol); 6482 __ bind(&is_symbol);
6506 } 6483 }
6507 6484
6508 // Check that both strings are sequential ASCII. 6485 // Check that both strings are sequential ASCII.
6509 Label runtime; 6486 Label runtime;
(...skipping 1104 matching lines...) Expand 10 before | Expand all | Expand 10 after
7614 __ bind(&fast_elements_case); 7591 __ bind(&fast_elements_case);
7615 GenerateCase(masm, FAST_ELEMENTS); 7592 GenerateCase(masm, FAST_ELEMENTS);
7616 } 7593 }
7617 7594
7618 7595
7619 #undef __ 7596 #undef __
7620 7597
7621 } } // namespace v8::internal 7598 } } // namespace v8::internal
7622 7599
7623 #endif // V8_TARGET_ARCH_MIPS 7600 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.h ('k') | src/mips/codegen-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698