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

Side by Side Diff: src/arm/stub-cache-arm.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/arm/macro-assembler-arm.cc ('k') | src/ia32/builtins-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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 ASSERT(!extra2.is(name)); 182 ASSERT(!extra2.is(name));
183 ASSERT(!extra2.is(scratch)); 183 ASSERT(!extra2.is(scratch));
184 ASSERT(!extra2.is(extra)); 184 ASSERT(!extra2.is(extra));
185 185
186 // Check scratch, extra and extra2 registers are valid. 186 // Check scratch, extra and extra2 registers are valid.
187 ASSERT(!scratch.is(no_reg)); 187 ASSERT(!scratch.is(no_reg));
188 ASSERT(!extra.is(no_reg)); 188 ASSERT(!extra.is(no_reg));
189 ASSERT(!extra2.is(no_reg)); 189 ASSERT(!extra2.is(no_reg));
190 190
191 // Check that the receiver isn't a smi. 191 // Check that the receiver isn't a smi.
192 __ tst(receiver, Operand(kSmiTagMask)); 192 __ JumpIfSmi(receiver, &miss);
193 __ b(eq, &miss);
194 193
195 // Get the map of the receiver and compute the hash. 194 // Get the map of the receiver and compute the hash.
196 __ ldr(scratch, FieldMemOperand(name, String::kHashFieldOffset)); 195 __ ldr(scratch, FieldMemOperand(name, String::kHashFieldOffset));
197 __ ldr(ip, FieldMemOperand(receiver, HeapObject::kMapOffset)); 196 __ ldr(ip, FieldMemOperand(receiver, HeapObject::kMapOffset));
198 __ add(scratch, scratch, Operand(ip)); 197 __ add(scratch, scratch, Operand(ip));
199 __ eor(scratch, scratch, Operand(flags)); 198 __ eor(scratch, scratch, Operand(flags));
200 __ and_(scratch, 199 __ and_(scratch,
201 scratch, 200 scratch,
202 Operand((kPrimaryTableSize - 1) << kHeapObjectTagSize)); 201 Operand((kPrimaryTableSize - 1) << kHeapObjectTagSize));
203 202
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 __ ldr(dst, FieldMemOperand(dst, offset)); 274 __ ldr(dst, FieldMemOperand(dst, offset));
276 } 275 }
277 } 276 }
278 277
279 278
280 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 279 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
281 Register receiver, 280 Register receiver,
282 Register scratch, 281 Register scratch,
283 Label* miss_label) { 282 Label* miss_label) {
284 // Check that the receiver isn't a smi. 283 // Check that the receiver isn't a smi.
285 __ tst(receiver, Operand(kSmiTagMask)); 284 __ JumpIfSmi(receiver, miss_label);
286 __ b(eq, miss_label);
287 285
288 // Check that the object is a JS array. 286 // Check that the object is a JS array.
289 __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE); 287 __ CompareObjectType(receiver, scratch, scratch, JS_ARRAY_TYPE);
290 __ b(ne, miss_label); 288 __ b(ne, miss_label);
291 289
292 // Load length directly from the JS array. 290 // Load length directly from the JS array.
293 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 291 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
294 __ Ret(); 292 __ Ret();
295 } 293 }
296 294
297 295
298 // Generate code to check if an object is a string. If the object is a 296 // Generate code to check if an object is a string. If the object is a
299 // heap object, its map's instance type is left in the scratch1 register. 297 // heap object, its map's instance type is left in the scratch1 register.
300 // If this is not needed, scratch1 and scratch2 may be the same register. 298 // If this is not needed, scratch1 and scratch2 may be the same register.
301 static void GenerateStringCheck(MacroAssembler* masm, 299 static void GenerateStringCheck(MacroAssembler* masm,
302 Register receiver, 300 Register receiver,
303 Register scratch1, 301 Register scratch1,
304 Register scratch2, 302 Register scratch2,
305 Label* smi, 303 Label* smi,
306 Label* non_string_object) { 304 Label* non_string_object) {
307 // Check that the receiver isn't a smi. 305 // Check that the receiver isn't a smi.
308 __ tst(receiver, Operand(kSmiTagMask)); 306 __ JumpIfSmi(receiver, smi);
309 __ b(eq, smi);
310 307
311 // Check that the object is a string. 308 // Check that the object is a string.
312 __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); 309 __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset));
313 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); 310 __ ldrb(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
314 __ and_(scratch2, scratch1, Operand(kIsNotStringMask)); 311 __ and_(scratch2, scratch1, Operand(kIsNotStringMask));
315 // The cast is to resolve the overload for the argument of 0x0. 312 // The cast is to resolve the overload for the argument of 0x0.
316 __ cmp(scratch2, Operand(static_cast<int32_t>(kStringTag))); 313 __ cmp(scratch2, Operand(static_cast<int32_t>(kStringTag)));
317 __ b(ne, non_string_object); 314 __ b(ne, non_string_object);
318 } 315 }
319 316
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 int index, 371 int index,
375 Map* transition, 372 Map* transition,
376 Register receiver_reg, 373 Register receiver_reg,
377 Register name_reg, 374 Register name_reg,
378 Register scratch, 375 Register scratch,
379 Label* miss_label) { 376 Label* miss_label) {
380 // r0 : value 377 // r0 : value
381 Label exit; 378 Label exit;
382 379
383 // Check that the receiver isn't a smi. 380 // Check that the receiver isn't a smi.
384 __ tst(receiver_reg, Operand(kSmiTagMask)); 381 __ JumpIfSmi(receiver_reg, miss_label);
385 __ b(eq, miss_label);
386 382
387 // Check that the map of the receiver hasn't changed. 383 // Check that the map of the receiver hasn't changed.
388 __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 384 __ ldr(scratch, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
389 __ cmp(scratch, Operand(Handle<Map>(object->map()))); 385 __ cmp(scratch, Operand(Handle<Map>(object->map())));
390 __ b(ne, miss_label); 386 __ b(ne, miss_label);
391 387
392 // Perform global security token check if needed. 388 // Perform global security token check if needed.
393 if (object->IsJSGlobalProxy()) { 389 if (object->IsJSGlobalProxy()) {
394 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); 390 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label);
395 } 391 }
(...skipping 28 matching lines...) Expand all
424 // face of a transition we can use the old map here because the size of the 420 // face of a transition we can use the old map here because the size of the
425 // object and the number of in-object properties is not going to change. 421 // object and the number of in-object properties is not going to change.
426 index -= object->map()->inobject_properties(); 422 index -= object->map()->inobject_properties();
427 423
428 if (index < 0) { 424 if (index < 0) {
429 // Set the property straight into the object. 425 // Set the property straight into the object.
430 int offset = object->map()->instance_size() + (index * kPointerSize); 426 int offset = object->map()->instance_size() + (index * kPointerSize);
431 __ str(r0, FieldMemOperand(receiver_reg, offset)); 427 __ str(r0, FieldMemOperand(receiver_reg, offset));
432 428
433 // Skip updating write barrier if storing a smi. 429 // Skip updating write barrier if storing a smi.
434 __ tst(r0, Operand(kSmiTagMask)); 430 __ JumpIfSmi(r0, &exit);
435 __ b(eq, &exit);
436 431
437 // Update the write barrier for the array address. 432 // Update the write barrier for the array address.
438 // Pass the now unused name_reg as a scratch register. 433 // Pass the now unused name_reg as a scratch register.
439 __ RecordWrite(receiver_reg, Operand(offset), name_reg, scratch); 434 __ RecordWrite(receiver_reg, Operand(offset), name_reg, scratch);
440 } else { 435 } else {
441 // Write to the properties array. 436 // Write to the properties array.
442 int offset = index * kPointerSize + FixedArray::kHeaderSize; 437 int offset = index * kPointerSize + FixedArray::kHeaderSize;
443 // Get the properties array 438 // Get the properties array
444 __ ldr(scratch, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 439 __ ldr(scratch, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
445 __ str(r0, FieldMemOperand(scratch, offset)); 440 __ str(r0, FieldMemOperand(scratch, offset));
446 441
447 // Skip updating write barrier if storing a smi. 442 // Skip updating write barrier if storing a smi.
448 __ tst(r0, Operand(kSmiTagMask)); 443 __ JumpIfSmi(r0, &exit);
449 __ b(eq, &exit);
450 444
451 // Update the write barrier for the array address. 445 // Update the write barrier for the array address.
452 // Ok to clobber receiver_reg and name_reg, since we return. 446 // Ok to clobber receiver_reg and name_reg, since we return.
453 __ RecordWrite(scratch, Operand(offset), name_reg, receiver_reg); 447 __ RecordWrite(scratch, Operand(offset), name_reg, receiver_reg);
454 } 448 }
455 449
456 // Return the value (register r0). 450 // Return the value (register r0).
457 __ bind(&exit); 451 __ bind(&exit);
458 __ Ret(); 452 __ Ret();
459 } 453 }
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 void StubCompiler::GenerateLoadField(JSObject* object, 1152 void StubCompiler::GenerateLoadField(JSObject* object,
1159 JSObject* holder, 1153 JSObject* holder,
1160 Register receiver, 1154 Register receiver,
1161 Register scratch1, 1155 Register scratch1,
1162 Register scratch2, 1156 Register scratch2,
1163 Register scratch3, 1157 Register scratch3,
1164 int index, 1158 int index,
1165 String* name, 1159 String* name,
1166 Label* miss) { 1160 Label* miss) {
1167 // Check that the receiver isn't a smi. 1161 // Check that the receiver isn't a smi.
1168 __ tst(receiver, Operand(kSmiTagMask)); 1162 __ JumpIfSmi(receiver, miss);
1169 __ b(eq, miss);
1170 1163
1171 // Check that the maps haven't changed. 1164 // Check that the maps haven't changed.
1172 Register reg = 1165 Register reg =
1173 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, 1166 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3,
1174 name, miss); 1167 name, miss);
1175 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); 1168 GenerateFastPropertyLoad(masm(), r0, reg, holder, index);
1176 __ Ret(); 1169 __ Ret();
1177 } 1170 }
1178 1171
1179 1172
1180 void StubCompiler::GenerateLoadConstant(JSObject* object, 1173 void StubCompiler::GenerateLoadConstant(JSObject* object,
1181 JSObject* holder, 1174 JSObject* holder,
1182 Register receiver, 1175 Register receiver,
1183 Register scratch1, 1176 Register scratch1,
1184 Register scratch2, 1177 Register scratch2,
1185 Register scratch3, 1178 Register scratch3,
1186 Object* value, 1179 Object* value,
1187 String* name, 1180 String* name,
1188 Label* miss) { 1181 Label* miss) {
1189 // Check that the receiver isn't a smi. 1182 // Check that the receiver isn't a smi.
1190 __ tst(receiver, Operand(kSmiTagMask)); 1183 __ JumpIfSmi(receiver, miss);
1191 __ b(eq, miss);
1192 1184
1193 // Check that the maps haven't changed. 1185 // Check that the maps haven't changed.
1194 Register reg = 1186 Register reg =
1195 CheckPrototypes(object, receiver, holder, 1187 CheckPrototypes(object, receiver, holder,
1196 scratch1, scratch2, scratch3, name, miss); 1188 scratch1, scratch2, scratch3, name, miss);
1197 1189
1198 // Return the constant value. 1190 // Return the constant value.
1199 __ mov(r0, Operand(Handle<Object>(value))); 1191 __ mov(r0, Operand(Handle<Object>(value)));
1200 __ Ret(); 1192 __ Ret();
1201 } 1193 }
1202 1194
1203 1195
1204 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, 1196 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
1205 JSObject* holder, 1197 JSObject* holder,
1206 Register receiver, 1198 Register receiver,
1207 Register name_reg, 1199 Register name_reg,
1208 Register scratch1, 1200 Register scratch1,
1209 Register scratch2, 1201 Register scratch2,
1210 Register scratch3, 1202 Register scratch3,
1211 AccessorInfo* callback, 1203 AccessorInfo* callback,
1212 String* name, 1204 String* name,
1213 Label* miss) { 1205 Label* miss) {
1214 // Check that the receiver isn't a smi. 1206 // Check that the receiver isn't a smi.
1215 __ tst(receiver, Operand(kSmiTagMask)); 1207 __ JumpIfSmi(receiver, miss);
1216 __ b(eq, miss);
1217 1208
1218 // Check that the maps haven't changed. 1209 // Check that the maps haven't changed.
1219 Register reg = 1210 Register reg =
1220 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, 1211 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3,
1221 name, miss); 1212 name, miss);
1222 1213
1223 // Build AccessorInfo::args_ list on the stack and push property name below 1214 // Build AccessorInfo::args_ list on the stack and push property name below
1224 // the exit frame to make GC aware of them and store pointers to them. 1215 // the exit frame to make GC aware of them and store pointers to them.
1225 __ push(receiver); 1216 __ push(receiver);
1226 __ mov(scratch2, sp); // scratch2 = AccessorInfo::args_ 1217 __ mov(scratch2, sp); // scratch2 = AccessorInfo::args_
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 // Get the number of arguments. 1410 // Get the number of arguments.
1420 const int argc = arguments().immediate(); 1411 const int argc = arguments().immediate();
1421 1412
1422 // Get the receiver from the stack. 1413 // Get the receiver from the stack.
1423 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); 1414 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
1424 1415
1425 // If the object is the holder then we know that it's a global 1416 // If the object is the holder then we know that it's a global
1426 // object which can only happen for contextual calls. In this case, 1417 // object which can only happen for contextual calls. In this case,
1427 // the receiver cannot be a smi. 1418 // the receiver cannot be a smi.
1428 if (object != holder) { 1419 if (object != holder) {
1429 __ tst(r0, Operand(kSmiTagMask)); 1420 __ JumpIfSmi(r0, miss);
1430 __ b(eq, miss);
1431 } 1421 }
1432 1422
1433 // Check that the maps haven't changed. 1423 // Check that the maps haven't changed.
1434 CheckPrototypes(object, r0, holder, r3, r1, r4, name, miss); 1424 CheckPrototypes(object, r0, holder, r3, r1, r4, name, miss);
1435 } 1425 }
1436 1426
1437 1427
1438 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, 1428 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell,
1439 JSFunction* function, 1429 JSFunction* function,
1440 Label* miss) { 1430 Label* miss) {
1441 // Get the value from the cell. 1431 // Get the value from the cell.
1442 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); 1432 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell)));
1443 __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); 1433 __ ldr(r1, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset));
1444 1434
1445 // Check that the cell contains the same function. 1435 // Check that the cell contains the same function.
1446 if (heap()->InNewSpace(function)) { 1436 if (heap()->InNewSpace(function)) {
1447 // We can't embed a pointer to a function in new space so we have 1437 // We can't embed a pointer to a function in new space so we have
1448 // to verify that the shared function info is unchanged. This has 1438 // to verify that the shared function info is unchanged. This has
1449 // the nice side effect that multiple closures based on the same 1439 // the nice side effect that multiple closures based on the same
1450 // function can all use this call IC. Before we load through the 1440 // function can all use this call IC. Before we load through the
1451 // function, we have to verify that it still is a function. 1441 // function, we have to verify that it still is a function.
1452 __ tst(r1, Operand(kSmiTagMask)); 1442 __ JumpIfSmi(r1, miss);
1453 __ b(eq, miss);
1454 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE); 1443 __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
1455 __ b(ne, miss); 1444 __ b(ne, miss);
1456 1445
1457 // Check the shared function info. Make sure it hasn't changed. 1446 // Check the shared function info. Make sure it hasn't changed.
1458 __ Move(r3, Handle<SharedFunctionInfo>(function->shared())); 1447 __ Move(r3, Handle<SharedFunctionInfo>(function->shared()));
1459 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 1448 __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1460 __ cmp(r4, r3); 1449 __ cmp(r4, r3);
1461 __ b(ne, miss); 1450 __ b(ne, miss);
1462 } else { 1451 } else {
1463 __ cmp(r1, Operand(Handle<JSFunction>(function))); 1452 __ cmp(r1, Operand(Handle<JSFunction>(function)));
(...skipping 24 matching lines...) Expand all
1488 // ----------------------------------- 1477 // -----------------------------------
1489 Label miss; 1478 Label miss;
1490 1479
1491 GenerateNameCheck(name, &miss); 1480 GenerateNameCheck(name, &miss);
1492 1481
1493 const int argc = arguments().immediate(); 1482 const int argc = arguments().immediate();
1494 1483
1495 // Get the receiver of the function from the stack into r0. 1484 // Get the receiver of the function from the stack into r0.
1496 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); 1485 __ ldr(r0, MemOperand(sp, argc * kPointerSize));
1497 // Check that the receiver isn't a smi. 1486 // Check that the receiver isn't a smi.
1498 __ tst(r0, Operand(kSmiTagMask)); 1487 __ JumpIfSmi(r0, &miss);
1499 __ b(eq, &miss);
1500 1488
1501 // Do the right check and compute the holder register. 1489 // Do the right check and compute the holder register.
1502 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss); 1490 Register reg = CheckPrototypes(object, r0, holder, r1, r3, r4, name, &miss);
1503 GenerateFastPropertyLoad(masm(), r1, reg, holder, index); 1491 GenerateFastPropertyLoad(masm(), r1, reg, holder, index);
1504 1492
1505 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_); 1493 GenerateCallFunction(masm(), object, arguments(), &miss, extra_ic_state_);
1506 1494
1507 // Handle call cache miss. 1495 // Handle call cache miss.
1508 __ bind(&miss); 1496 __ bind(&miss);
1509 MaybeObject* maybe_result = GenerateMissBranch(); 1497 MaybeObject* maybe_result = GenerateMissBranch();
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1960 // arguments, bail out to the regular call. 1948 // arguments, bail out to the regular call.
1961 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 1949 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
1962 1950
1963 Label miss; 1951 Label miss;
1964 GenerateNameCheck(name, &miss); 1952 GenerateNameCheck(name, &miss);
1965 1953
1966 if (cell == NULL) { 1954 if (cell == NULL) {
1967 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 1955 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
1968 1956
1969 STATIC_ASSERT(kSmiTag == 0); 1957 STATIC_ASSERT(kSmiTag == 0);
1970 __ tst(r1, Operand(kSmiTagMask)); 1958 __ JumpIfSmi(r1, &miss);
1971 __ b(eq, &miss);
1972 1959
1973 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, 1960 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
1974 &miss); 1961 &miss);
1975 } else { 1962 } else {
1976 ASSERT(cell->value() == function); 1963 ASSERT(cell->value() == function);
1977 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); 1964 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
1978 GenerateLoadFunctionFromCell(cell, function, &miss); 1965 GenerateLoadFunctionFromCell(cell, function, &miss);
1979 } 1966 }
1980 1967
1981 // Load the char code argument. 1968 // Load the char code argument.
1982 Register code = r1; 1969 Register code = r1;
1983 __ ldr(code, MemOperand(sp, 0 * kPointerSize)); 1970 __ ldr(code, MemOperand(sp, 0 * kPointerSize));
1984 1971
1985 // Check the code is a smi. 1972 // Check the code is a smi.
1986 Label slow; 1973 Label slow;
1987 STATIC_ASSERT(kSmiTag == 0); 1974 STATIC_ASSERT(kSmiTag == 0);
1988 __ tst(code, Operand(kSmiTagMask)); 1975 __ JumpIfNotSmi(code, &slow);
1989 __ b(ne, &slow);
1990 1976
1991 // Convert the smi code to uint16. 1977 // Convert the smi code to uint16.
1992 __ and_(code, code, Operand(Smi::FromInt(0xffff))); 1978 __ and_(code, code, Operand(Smi::FromInt(0xffff)));
1993 1979
1994 StringCharFromCodeGenerator char_from_code_generator(code, r0); 1980 StringCharFromCodeGenerator char_from_code_generator(code, r0);
1995 char_from_code_generator.GenerateFast(masm()); 1981 char_from_code_generator.GenerateFast(masm());
1996 __ Drop(argc + 1); 1982 __ Drop(argc + 1);
1997 __ Ret(); 1983 __ Ret();
1998 1984
1999 StubRuntimeCallHelper call_helper; 1985 StubRuntimeCallHelper call_helper;
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
2181 // arguments, bail out to the regular call. 2167 // arguments, bail out to the regular call.
2182 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); 2168 if (!object->IsJSObject() || argc != 1) return heap()->undefined_value();
2183 2169
2184 Label miss; 2170 Label miss;
2185 GenerateNameCheck(name, &miss); 2171 GenerateNameCheck(name, &miss);
2186 2172
2187 if (cell == NULL) { 2173 if (cell == NULL) {
2188 __ ldr(r1, MemOperand(sp, 1 * kPointerSize)); 2174 __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
2189 2175
2190 STATIC_ASSERT(kSmiTag == 0); 2176 STATIC_ASSERT(kSmiTag == 0);
2191 __ tst(r1, Operand(kSmiTagMask)); 2177 __ JumpIfSmi(r1, &miss);
2192 __ b(eq, &miss);
2193 2178
2194 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, 2179 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
2195 &miss); 2180 &miss);
2196 } else { 2181 } else {
2197 ASSERT(cell->value() == function); 2182 ASSERT(cell->value() == function);
2198 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); 2183 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
2199 GenerateLoadFunctionFromCell(cell, function, &miss); 2184 GenerateLoadFunctionFromCell(cell, function, &miss);
2200 } 2185 }
2201 2186
2202 // Load the (only) argument into r0. 2187 // Load the (only) argument into r0.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2285 2270
2286 Label miss, miss_before_stack_reserved; 2271 Label miss, miss_before_stack_reserved;
2287 2272
2288 GenerateNameCheck(name, &miss_before_stack_reserved); 2273 GenerateNameCheck(name, &miss_before_stack_reserved);
2289 2274
2290 // Get the receiver from the stack. 2275 // Get the receiver from the stack.
2291 const int argc = arguments().immediate(); 2276 const int argc = arguments().immediate();
2292 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2277 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
2293 2278
2294 // Check that the receiver isn't a smi. 2279 // Check that the receiver isn't a smi.
2295 __ tst(r1, Operand(kSmiTagMask)); 2280 __ JumpIfSmi(r1, &miss_before_stack_reserved);
2296 __ b(eq, &miss_before_stack_reserved);
2297 2281
2298 __ IncrementCounter(counters->call_const(), 1, r0, r3); 2282 __ IncrementCounter(counters->call_const(), 1, r0, r3);
2299 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3); 2283 __ IncrementCounter(counters->call_const_fast_api(), 1, r0, r3);
2300 2284
2301 ReserveSpaceForFastApiCall(masm(), r0); 2285 ReserveSpaceForFastApiCall(masm(), r0);
2302 2286
2303 // Check that the maps haven't changed and find a Holder as a side effect. 2287 // Check that the maps haven't changed and find a Holder as a side effect.
2304 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, 2288 CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name,
2305 depth, &miss); 2289 depth, &miss);
2306 2290
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2340 Label miss; 2324 Label miss;
2341 2325
2342 GenerateNameCheck(name, &miss); 2326 GenerateNameCheck(name, &miss);
2343 2327
2344 // Get the receiver from the stack 2328 // Get the receiver from the stack
2345 const int argc = arguments().immediate(); 2329 const int argc = arguments().immediate();
2346 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); 2330 __ ldr(r1, MemOperand(sp, argc * kPointerSize));
2347 2331
2348 // Check that the receiver isn't a smi. 2332 // Check that the receiver isn't a smi.
2349 if (check != NUMBER_CHECK) { 2333 if (check != NUMBER_CHECK) {
2350 __ tst(r1, Operand(kSmiTagMask)); 2334 __ JumpIfSmi(r1, &miss);
2351 __ b(eq, &miss);
2352 } 2335 }
2353 2336
2354 // Make sure that it's okay not to patch the on stack receiver 2337 // Make sure that it's okay not to patch the on stack receiver
2355 // unless we're doing a receiver map check. 2338 // unless we're doing a receiver map check.
2356 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2339 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2357 2340
2358 SharedFunctionInfo* function_info = function->shared(); 2341 SharedFunctionInfo* function_info = function->shared();
2359 switch (check) { 2342 switch (check) {
2360 case RECEIVER_MAP_CHECK: 2343 case RECEIVER_MAP_CHECK:
2361 __ IncrementCounter(masm()->isolate()->counters()->call_const(), 2344 __ IncrementCounter(masm()->isolate()->counters()->call_const(),
(...skipping 29 matching lines...) Expand all
2391 break; 2374 break;
2392 2375
2393 case NUMBER_CHECK: { 2376 case NUMBER_CHECK: {
2394 if (!function->IsBuiltin() && !function_info->strict_mode()) { 2377 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2395 // Calling non-strict non-builtins with a value as the receiver 2378 // Calling non-strict non-builtins with a value as the receiver
2396 // requires boxing. 2379 // requires boxing.
2397 __ jmp(&miss); 2380 __ jmp(&miss);
2398 } else { 2381 } else {
2399 Label fast; 2382 Label fast;
2400 // Check that the object is a smi or a heap number. 2383 // Check that the object is a smi or a heap number.
2401 __ tst(r1, Operand(kSmiTagMask)); 2384 __ JumpIfSmi(r1, &fast);
2402 __ b(eq, &fast);
2403 __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE); 2385 __ CompareObjectType(r1, r0, r0, HEAP_NUMBER_TYPE);
2404 __ b(ne, &miss); 2386 __ b(ne, &miss);
2405 __ bind(&fast); 2387 __ bind(&fast);
2406 // Check that the maps starting from the prototype haven't changed. 2388 // Check that the maps starting from the prototype haven't changed.
2407 GenerateDirectLoadGlobalFunctionPrototype( 2389 GenerateDirectLoadGlobalFunctionPrototype(
2408 masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss); 2390 masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss);
2409 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3, 2391 CheckPrototypes(JSObject::cast(object->GetPrototype()), r0, holder, r3,
2410 r1, r4, name, &miss); 2392 r1, r4, name, &miss);
2411 } 2393 }
2412 break; 2394 break;
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
2612 String* name) { 2594 String* name) {
2613 // ----------- S t a t e ------------- 2595 // ----------- S t a t e -------------
2614 // -- r0 : value 2596 // -- r0 : value
2615 // -- r1 : receiver 2597 // -- r1 : receiver
2616 // -- r2 : name 2598 // -- r2 : name
2617 // -- lr : return address 2599 // -- lr : return address
2618 // ----------------------------------- 2600 // -----------------------------------
2619 Label miss; 2601 Label miss;
2620 2602
2621 // Check that the object isn't a smi. 2603 // Check that the object isn't a smi.
2622 __ tst(r1, Operand(kSmiTagMask)); 2604 __ JumpIfSmi(r1, &miss);
2623 __ b(eq, &miss);
2624 2605
2625 // Check that the map of the object hasn't changed. 2606 // Check that the map of the object hasn't changed.
2626 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); 2607 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
2627 __ cmp(r3, Operand(Handle<Map>(object->map()))); 2608 __ cmp(r3, Operand(Handle<Map>(object->map())));
2628 __ b(ne, &miss); 2609 __ b(ne, &miss);
2629 2610
2630 // Perform global security token check if needed. 2611 // Perform global security token check if needed.
2631 if (object->IsJSGlobalProxy()) { 2612 if (object->IsJSGlobalProxy()) {
2632 __ CheckAccessGlobalProxy(r1, r3, &miss); 2613 __ CheckAccessGlobalProxy(r1, r3, &miss);
2633 } 2614 }
(...skipping 26 matching lines...) Expand all
2660 String* name) { 2641 String* name) {
2661 // ----------- S t a t e ------------- 2642 // ----------- S t a t e -------------
2662 // -- r0 : value 2643 // -- r0 : value
2663 // -- r1 : receiver 2644 // -- r1 : receiver
2664 // -- r2 : name 2645 // -- r2 : name
2665 // -- lr : return address 2646 // -- lr : return address
2666 // ----------------------------------- 2647 // -----------------------------------
2667 Label miss; 2648 Label miss;
2668 2649
2669 // Check that the object isn't a smi. 2650 // Check that the object isn't a smi.
2670 __ tst(r1, Operand(kSmiTagMask)); 2651 __ JumpIfSmi(r1, &miss);
2671 __ b(eq, &miss);
2672 2652
2673 // Check that the map of the object hasn't changed. 2653 // Check that the map of the object hasn't changed.
2674 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); 2654 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
2675 __ cmp(r3, Operand(Handle<Map>(receiver->map()))); 2655 __ cmp(r3, Operand(Handle<Map>(receiver->map())));
2676 __ b(ne, &miss); 2656 __ b(ne, &miss);
2677 2657
2678 // Perform global security token check if needed. 2658 // Perform global security token check if needed.
2679 if (receiver->IsJSGlobalProxy()) { 2659 if (receiver->IsJSGlobalProxy()) {
2680 __ CheckAccessGlobalProxy(r1, r3, &miss); 2660 __ CheckAccessGlobalProxy(r1, r3, &miss);
2681 } 2661 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2752 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2732 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2753 JSObject* object, 2733 JSObject* object,
2754 JSObject* last) { 2734 JSObject* last) {
2755 // ----------- S t a t e ------------- 2735 // ----------- S t a t e -------------
2756 // -- r0 : receiver 2736 // -- r0 : receiver
2757 // -- lr : return address 2737 // -- lr : return address
2758 // ----------------------------------- 2738 // -----------------------------------
2759 Label miss; 2739 Label miss;
2760 2740
2761 // Check that receiver is not a smi. 2741 // Check that receiver is not a smi.
2762 __ tst(r0, Operand(kSmiTagMask)); 2742 __ JumpIfSmi(r0, &miss);
2763 __ b(eq, &miss);
2764 2743
2765 // Check the maps of the full prototype chain. 2744 // Check the maps of the full prototype chain.
2766 CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss); 2745 CheckPrototypes(object, r0, last, r3, r1, r4, name, &miss);
2767 2746
2768 // If the last object in the prototype chain is a global object, 2747 // If the last object in the prototype chain is a global object,
2769 // check that the global property cell is empty. 2748 // check that the global property cell is empty.
2770 if (last->IsGlobalObject()) { 2749 if (last->IsGlobalObject()) {
2771 MaybeObject* cell = GenerateCheckPropertyCell(masm(), 2750 MaybeObject* cell = GenerateCheckPropertyCell(masm(),
2772 GlobalObject::cast(last), 2751 GlobalObject::cast(last),
2773 name, 2752 name,
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2897 // -- r0 : receiver 2876 // -- r0 : receiver
2898 // -- r2 : name 2877 // -- r2 : name
2899 // -- lr : return address 2878 // -- lr : return address
2900 // ----------------------------------- 2879 // -----------------------------------
2901 Label miss; 2880 Label miss;
2902 2881
2903 // If the object is the holder then we know that it's a global 2882 // If the object is the holder then we know that it's a global
2904 // object which can only happen for contextual calls. In this case, 2883 // object which can only happen for contextual calls. In this case,
2905 // the receiver cannot be a smi. 2884 // the receiver cannot be a smi.
2906 if (object != holder) { 2885 if (object != holder) {
2907 __ tst(r0, Operand(kSmiTagMask)); 2886 __ JumpIfSmi(r0, &miss);
2908 __ b(eq, &miss);
2909 } 2887 }
2910 2888
2911 // Check that the map of the global has not changed. 2889 // Check that the map of the global has not changed.
2912 CheckPrototypes(object, r0, holder, r3, r4, r1, name, &miss); 2890 CheckPrototypes(object, r0, holder, r3, r4, r1, name, &miss);
2913 2891
2914 // Get the value from the cell. 2892 // Get the value from the cell.
2915 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell))); 2893 __ mov(r3, Operand(Handle<JSGlobalPropertyCell>(cell)));
2916 __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset)); 2894 __ ldr(r4, FieldMemOperand(r3, JSGlobalPropertyCell::kValueOffset));
2917 2895
2918 // Check for deleted property if property can actually be deleted. 2896 // Check for deleted property if property can actually be deleted.
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
3282 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 3260 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
3283 __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kDebugInfoOffset)); 3261 __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kDebugInfoOffset));
3284 __ cmp(r2, r7); 3262 __ cmp(r2, r7);
3285 __ b(ne, &generic_stub_call); 3263 __ b(ne, &generic_stub_call);
3286 #endif 3264 #endif
3287 3265
3288 // Load the initial map and verify that it is in fact a map. 3266 // Load the initial map and verify that it is in fact a map.
3289 // r1: constructor function 3267 // r1: constructor function
3290 // r7: undefined 3268 // r7: undefined
3291 __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); 3269 __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
3292 __ tst(r2, Operand(kSmiTagMask)); 3270 __ JumpIfSmi(r2, &generic_stub_call);
3293 __ b(eq, &generic_stub_call);
3294 __ CompareObjectType(r2, r3, r4, MAP_TYPE); 3271 __ CompareObjectType(r2, r3, r4, MAP_TYPE);
3295 __ b(ne, &generic_stub_call); 3272 __ b(ne, &generic_stub_call);
3296 3273
3297 #ifdef DEBUG 3274 #ifdef DEBUG
3298 // Cannot construct functions this way. 3275 // Cannot construct functions this way.
3299 // r0: argc 3276 // r0: argc
3300 // r1: constructor function 3277 // r1: constructor function
3301 // r2: initial map 3278 // r2: initial map
3302 // r7: undefined 3279 // r7: undefined
3303 __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE); 3280 __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE);
(...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after
4196 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 4173 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
4197 __ Jump(ic, RelocInfo::CODE_TARGET); 4174 __ Jump(ic, RelocInfo::CODE_TARGET);
4198 } 4175 }
4199 4176
4200 4177
4201 #undef __ 4178 #undef __
4202 4179
4203 } } // namespace v8::internal 4180 } } // namespace v8::internal
4204 4181
4205 #endif // V8_TARGET_ARCH_ARM 4182 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/ia32/builtins-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698