OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |