| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 __ Drop(4); | 591 __ Drop(4); |
| 592 } | 592 } |
| 593 | 593 |
| 594 | 594 |
| 595 // Generates call to FastHandleApiCall builtin. | 595 // Generates call to FastHandleApiCall builtin. |
| 596 static void GenerateFastApiCall(MacroAssembler* masm, | 596 static void GenerateFastApiCall(MacroAssembler* masm, |
| 597 const CallOptimization& optimization, | 597 const CallOptimization& optimization, |
| 598 int argc) { | 598 int argc) { |
| 599 // Get the function and setup the context. | 599 // Get the function and setup the context. |
| 600 JSFunction* function = optimization.constant_function(); | 600 JSFunction* function = optimization.constant_function(); |
| 601 __ mov(r7, Operand(Handle<JSFunction>(function))); | 601 __ mov(r5, Operand(Handle<JSFunction>(function))); |
| 602 __ ldr(cp, FieldMemOperand(r7, JSFunction::kContextOffset)); | 602 __ ldr(cp, FieldMemOperand(r5, JSFunction::kContextOffset)); |
| 603 | 603 |
| 604 // Pass the additional arguments FastHandleApiCall expects. | 604 // Pass the additional arguments FastHandleApiCall expects. |
| 605 bool info_loaded = false; | 605 bool info_loaded = false; |
| 606 Object* callback = optimization.api_call_info()->callback(); | 606 Object* callback = optimization.api_call_info()->callback(); |
| 607 if (Heap::InNewSpace(callback)) { | 607 if (Heap::InNewSpace(callback)) { |
| 608 info_loaded = true; | 608 info_loaded = true; |
| 609 __ Move(r0, Handle<CallHandlerInfo>(optimization.api_call_info())); | 609 __ Move(r0, Handle<CallHandlerInfo>(optimization.api_call_info())); |
| 610 __ ldr(r6, FieldMemOperand(r0, CallHandlerInfo::kCallbackOffset)); | 610 __ ldr(r7, FieldMemOperand(r0, CallHandlerInfo::kCallbackOffset)); |
| 611 } else { | 611 } else { |
| 612 __ Move(r6, Handle<Object>(callback)); | 612 __ Move(r7, Handle<Object>(callback)); |
| 613 } | 613 } |
| 614 Object* call_data = optimization.api_call_info()->data(); | 614 Object* call_data = optimization.api_call_info()->data(); |
| 615 if (Heap::InNewSpace(call_data)) { | 615 if (Heap::InNewSpace(call_data)) { |
| 616 if (!info_loaded) { | 616 if (!info_loaded) { |
| 617 __ Move(r0, Handle<CallHandlerInfo>(optimization.api_call_info())); | 617 __ Move(r0, Handle<CallHandlerInfo>(optimization.api_call_info())); |
| 618 } | 618 } |
| 619 __ ldr(r5, FieldMemOperand(r0, CallHandlerInfo::kDataOffset)); | 619 __ ldr(r6, FieldMemOperand(r0, CallHandlerInfo::kDataOffset)); |
| 620 } else { | 620 } else { |
| 621 __ Move(r5, Handle<Object>(call_data)); | 621 __ Move(r6, Handle<Object>(call_data)); |
| 622 } | 622 } |
| 623 | 623 |
| 624 __ add(sp, sp, Operand(1 * kPointerSize)); | 624 __ add(sp, sp, Operand(1 * kPointerSize)); |
| 625 __ stm(ia, sp, r5.bit() | r6.bit() | r7.bit()); | 625 __ stm(ia, sp, r5.bit() | r6.bit() | r7.bit()); |
| 626 __ sub(sp, sp, Operand(1 * kPointerSize)); | 626 __ sub(sp, sp, Operand(1 * kPointerSize)); |
| 627 | 627 |
| 628 // Set the number of arguments. | 628 // Set the number of arguments. |
| 629 __ mov(r0, Operand(argc + 4)); | 629 __ mov(r0, Operand(argc + 4)); |
| 630 | 630 |
| 631 // Jump to the fast api call builtin (tail call). | 631 // Jump to the fast api call builtin (tail call). |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 __ tst(receiver, Operand(kSmiTagMask)); | 1075 __ tst(receiver, Operand(kSmiTagMask)); |
| 1076 __ b(eq, miss); | 1076 __ b(eq, miss); |
| 1077 | 1077 |
| 1078 // Check that the maps haven't changed. | 1078 // Check that the maps haven't changed. |
| 1079 Register reg = | 1079 Register reg = |
| 1080 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, | 1080 CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, |
| 1081 name, miss); | 1081 name, miss); |
| 1082 | 1082 |
| 1083 // Push the arguments on the JS stack of the caller. | 1083 // Push the arguments on the JS stack of the caller. |
| 1084 __ push(receiver); // Receiver. | 1084 __ push(receiver); // Receiver. |
| 1085 __ push(reg); // Holder. | 1085 __ mov(scratch3, Operand(Handle<AccessorInfo>(callback))); // callback data |
| 1086 __ mov(ip, Operand(Handle<AccessorInfo>(callback))); // callback data | 1086 __ ldr(ip, FieldMemOperand(scratch3, AccessorInfo::kDataOffset)); |
| 1087 __ ldr(reg, FieldMemOperand(ip, AccessorInfo::kDataOffset)); | 1087 __ Push(reg, ip, scratch3, name_reg); |
| 1088 __ Push(ip, reg, name_reg); | |
| 1089 | 1088 |
| 1090 // Do tail-call to the runtime system. | 1089 // Do tail-call to the runtime system. |
| 1091 ExternalReference load_callback_property = | 1090 ExternalReference load_callback_property = |
| 1092 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | 1091 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); |
| 1093 __ TailCallExternalReference(load_callback_property, 5, 1); | 1092 __ TailCallExternalReference(load_callback_property, 5, 1); |
| 1094 | 1093 |
| 1095 return true; | 1094 return true; |
| 1096 } | 1095 } |
| 1097 | 1096 |
| 1098 | 1097 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1201 ASSERT(callback != NULL); | 1200 ASSERT(callback != NULL); |
| 1202 ASSERT(callback->getter() != NULL); | 1201 ASSERT(callback->getter() != NULL); |
| 1203 | 1202 |
| 1204 // Tail call to runtime. | 1203 // Tail call to runtime. |
| 1205 // Important invariant in CALLBACKS case: the code above must be | 1204 // Important invariant in CALLBACKS case: the code above must be |
| 1206 // structured to never clobber |receiver| register. | 1205 // structured to never clobber |receiver| register. |
| 1207 __ Move(scratch2, Handle<AccessorInfo>(callback)); | 1206 __ Move(scratch2, Handle<AccessorInfo>(callback)); |
| 1208 // holder_reg is either receiver or scratch1. | 1207 // holder_reg is either receiver or scratch1. |
| 1209 if (!receiver.is(holder_reg)) { | 1208 if (!receiver.is(holder_reg)) { |
| 1210 ASSERT(scratch1.is(holder_reg)); | 1209 ASSERT(scratch1.is(holder_reg)); |
| 1211 __ Push(receiver, holder_reg, scratch2); | 1210 __ Push(receiver, holder_reg); |
| 1212 __ ldr(scratch1, | 1211 __ ldr(scratch3, |
| 1213 FieldMemOperand(holder_reg, AccessorInfo::kDataOffset)); | 1212 FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); |
| 1214 __ Push(scratch1, name_reg); | 1213 __ Push(scratch3, scratch2, name_reg); |
| 1215 } else { | 1214 } else { |
| 1216 __ push(receiver); | 1215 __ push(receiver); |
| 1217 __ ldr(scratch1, | 1216 __ ldr(scratch3, |
| 1218 FieldMemOperand(holder_reg, AccessorInfo::kDataOffset)); | 1217 FieldMemOperand(scratch2, AccessorInfo::kDataOffset)); |
| 1219 __ Push(holder_reg, scratch2, scratch1, name_reg); | 1218 __ Push(holder_reg, scratch3, scratch2, name_reg); |
| 1220 } | 1219 } |
| 1221 | 1220 |
| 1222 ExternalReference ref = | 1221 ExternalReference ref = |
| 1223 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); | 1222 ExternalReference(IC_Utility(IC::kLoadCallbackProperty)); |
| 1224 __ TailCallExternalReference(ref, 5, 1); | 1223 __ TailCallExternalReference(ref, 5, 1); |
| 1225 } | 1224 } |
| 1226 } else { // !compile_followup_inline | 1225 } else { // !compile_followup_inline |
| 1227 // Call the runtime system to load the interceptor. | 1226 // Call the runtime system to load the interceptor. |
| 1228 // Check that the maps haven't changed. | 1227 // Check that the maps haven't changed. |
| 1229 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, | 1228 Register holder_reg = CheckPrototypes(object, receiver, interceptor_holder, |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1353 | 1352 |
| 1354 | 1353 |
| 1355 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, | 1354 MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, |
| 1356 JSObject* holder, | 1355 JSObject* holder, |
| 1357 JSGlobalPropertyCell* cell, | 1356 JSGlobalPropertyCell* cell, |
| 1358 JSFunction* function, | 1357 JSFunction* function, |
| 1359 String* name) { | 1358 String* name) { |
| 1360 // ----------- S t a t e ------------- | 1359 // ----------- S t a t e ------------- |
| 1361 // -- r2 : name | 1360 // -- r2 : name |
| 1362 // -- lr : return address | 1361 // -- lr : return address |
| 1362 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1363 // -- ... |
| 1364 // -- sp[argc * 4] : receiver |
| 1363 // ----------------------------------- | 1365 // ----------------------------------- |
| 1364 | 1366 |
| 1365 // TODO(639): faster implementation. | |
| 1366 | |
| 1367 // If object is not an array, bail out to regular call. | 1367 // If object is not an array, bail out to regular call. |
| 1368 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); | 1368 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); |
| 1369 | 1369 |
| 1370 Label miss; | 1370 Label miss; |
| 1371 | 1371 |
| 1372 GenerateNameCheck(name, &miss); | 1372 GenerateNameCheck(name, &miss); |
| 1373 | 1373 |
| 1374 Register receiver = r1; |
| 1375 |
| 1374 // Get the receiver from the stack | 1376 // Get the receiver from the stack |
| 1375 const int argc = arguments().immediate(); | 1377 const int argc = arguments().immediate(); |
| 1376 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 1378 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1377 | 1379 |
| 1378 // Check that the receiver isn't a smi. | 1380 // Check that the receiver isn't a smi. |
| 1379 __ tst(r1, Operand(kSmiTagMask)); | 1381 __ BranchOnSmi(receiver, &miss); |
| 1380 __ b(eq, &miss); | |
| 1381 | 1382 |
| 1382 // Check that the maps haven't changed. | 1383 // Check that the maps haven't changed. |
| 1383 CheckPrototypes(JSObject::cast(object), r1, holder, r3, r0, r4, name, &miss); | 1384 CheckPrototypes(JSObject::cast(object), receiver, |
| 1385 holder, r3, r0, r4, name, &miss); |
| 1384 | 1386 |
| 1385 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush), | 1387 if (argc == 0) { |
| 1386 argc + 1, | 1388 // Nothing to do, just return the length. |
| 1387 1); | 1389 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1390 __ Drop(argc + 1); |
| 1391 __ Ret(); |
| 1392 } else { |
| 1393 Label call_builtin; |
| 1394 |
| 1395 Register elements = r3; |
| 1396 Register end_elements = r5; |
| 1397 |
| 1398 // Get the elements array of the object. |
| 1399 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); |
| 1400 |
| 1401 // Check that the elements are in fast mode and writable. |
| 1402 __ CheckMap(elements, r0, |
| 1403 Heap::kFixedArrayMapRootIndex, &call_builtin, true); |
| 1404 |
| 1405 if (argc == 1) { // Otherwise fall through to call the builtin. |
| 1406 Label exit, with_write_barrier, attempt_to_grow_elements; |
| 1407 |
| 1408 // Get the array's length into r0 and calculate new length. |
| 1409 __ ldr(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1410 STATIC_ASSERT(kSmiTagSize == 1); |
| 1411 STATIC_ASSERT(kSmiTag == 0); |
| 1412 __ add(r0, r0, Operand(Smi::FromInt(argc))); |
| 1413 |
| 1414 // Get the element's length. |
| 1415 __ ldr(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
| 1416 |
| 1417 // Check if we could survive without allocation. |
| 1418 __ cmp(r0, r4); |
| 1419 __ b(gt, &attempt_to_grow_elements); |
| 1420 |
| 1421 // Save new length. |
| 1422 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1423 |
| 1424 // Push the element. |
| 1425 __ ldr(r4, MemOperand(sp, (argc - 1) * kPointerSize)); |
| 1426 // We may need a register containing the address end_elements below, |
| 1427 // so write back the value in end_elements. |
| 1428 __ add(end_elements, elements, |
| 1429 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 1430 const int kEndElementsOffset = |
| 1431 FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; |
| 1432 __ str(r4, MemOperand(end_elements, kEndElementsOffset, PreIndex)); |
| 1433 |
| 1434 // Check for a smi. |
| 1435 __ BranchOnNotSmi(r4, &with_write_barrier); |
| 1436 __ bind(&exit); |
| 1437 __ Drop(argc + 1); |
| 1438 __ Ret(); |
| 1439 |
| 1440 __ bind(&with_write_barrier); |
| 1441 __ InNewSpace(elements, r4, eq, &exit); |
| 1442 __ RecordWriteHelper(elements, end_elements, r4); |
| 1443 __ Drop(argc + 1); |
| 1444 __ Ret(); |
| 1445 |
| 1446 __ bind(&attempt_to_grow_elements); |
| 1447 // r0: array's length + 1. |
| 1448 // r4: elements' length. |
| 1449 |
| 1450 if (!FLAG_inline_new) { |
| 1451 __ b(&call_builtin); |
| 1452 } |
| 1453 |
| 1454 ExternalReference new_space_allocation_top = |
| 1455 ExternalReference::new_space_allocation_top_address(); |
| 1456 ExternalReference new_space_allocation_limit = |
| 1457 ExternalReference::new_space_allocation_limit_address(); |
| 1458 |
| 1459 const int kAllocationDelta = 4; |
| 1460 // Load top and check if it is the end of elements. |
| 1461 __ add(end_elements, elements, |
| 1462 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 1463 __ add(end_elements, end_elements, Operand(kEndElementsOffset)); |
| 1464 __ mov(r7, Operand(new_space_allocation_top)); |
| 1465 __ ldr(r6, MemOperand(r7)); |
| 1466 __ cmp(end_elements, r6); |
| 1467 __ b(ne, &call_builtin); |
| 1468 |
| 1469 __ mov(r9, Operand(new_space_allocation_limit)); |
| 1470 __ ldr(r9, MemOperand(r9)); |
| 1471 __ add(r6, r6, Operand(kAllocationDelta * kPointerSize)); |
| 1472 __ cmp(r6, r9); |
| 1473 __ b(hi, &call_builtin); |
| 1474 |
| 1475 // We fit and could grow elements. |
| 1476 // Update new_space_allocation_top. |
| 1477 __ str(r6, MemOperand(r7)); |
| 1478 // Push the argument. |
| 1479 __ ldr(r6, MemOperand(sp, (argc - 1) * kPointerSize)); |
| 1480 __ str(r6, MemOperand(end_elements)); |
| 1481 // Fill the rest with holes. |
| 1482 __ LoadRoot(r6, Heap::kTheHoleValueRootIndex); |
| 1483 for (int i = 1; i < kAllocationDelta; i++) { |
| 1484 __ str(r6, MemOperand(end_elements, i * kPointerSize)); |
| 1485 } |
| 1486 |
| 1487 // Update elements' and array's sizes. |
| 1488 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1489 __ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta))); |
| 1490 __ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
| 1491 |
| 1492 // Elements are in new space, so write barrier is not required. |
| 1493 __ Drop(argc + 1); |
| 1494 __ Ret(); |
| 1495 } |
| 1496 __ bind(&call_builtin); |
| 1497 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush), |
| 1498 argc + 1, |
| 1499 1); |
| 1500 } |
| 1388 | 1501 |
| 1389 // Handle call cache miss. | 1502 // Handle call cache miss. |
| 1390 __ bind(&miss); | 1503 __ bind(&miss); |
| 1391 Object* obj; | 1504 Object* obj; |
| 1392 { MaybeObject* maybe_obj = GenerateMissBranch(); | 1505 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1393 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1506 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1394 } | 1507 } |
| 1395 | 1508 |
| 1396 // Return the generated code. | 1509 // Return the generated code. |
| 1397 return GetCode(function); | 1510 return GetCode(function); |
| 1398 } | 1511 } |
| 1399 | 1512 |
| 1400 | 1513 |
| 1401 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, | 1514 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, |
| 1402 JSObject* holder, | 1515 JSObject* holder, |
| 1403 JSGlobalPropertyCell* cell, | 1516 JSGlobalPropertyCell* cell, |
| 1404 JSFunction* function, | 1517 JSFunction* function, |
| 1405 String* name) { | 1518 String* name) { |
| 1406 // ----------- S t a t e ------------- | 1519 // ----------- S t a t e ------------- |
| 1407 // -- r2 : name | 1520 // -- r2 : name |
| 1408 // -- lr : return address | 1521 // -- lr : return address |
| 1522 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1523 // -- ... |
| 1524 // -- sp[argc * 4] : receiver |
| 1409 // ----------------------------------- | 1525 // ----------------------------------- |
| 1410 | 1526 |
| 1411 // TODO(642): faster implementation. | |
| 1412 | |
| 1413 // If object is not an array, bail out to regular call. | 1527 // If object is not an array, bail out to regular call. |
| 1414 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); | 1528 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); |
| 1415 | 1529 |
| 1416 Label miss; | 1530 Label miss, return_undefined, call_builtin; |
| 1531 |
| 1532 Register receiver = r1; |
| 1533 Register elements = r3; |
| 1417 | 1534 |
| 1418 GenerateNameCheck(name, &miss); | 1535 GenerateNameCheck(name, &miss); |
| 1419 | 1536 |
| 1420 // Get the receiver from the stack | 1537 // Get the receiver from the stack |
| 1421 const int argc = arguments().immediate(); | 1538 const int argc = arguments().immediate(); |
| 1422 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 1539 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1423 | 1540 |
| 1424 // Check that the receiver isn't a smi. | 1541 // Check that the receiver isn't a smi. |
| 1425 __ tst(r1, Operand(kSmiTagMask)); | 1542 __ BranchOnSmi(receiver, &miss); |
| 1426 __ b(eq, &miss); | |
| 1427 | 1543 |
| 1428 // Check that the maps haven't changed. | 1544 // Check that the maps haven't changed. |
| 1429 CheckPrototypes(JSObject::cast(object), r1, holder, r3, r0, r4, name, &miss); | 1545 CheckPrototypes(JSObject::cast(object), |
| 1546 receiver, holder, elements, r4, r0, name, &miss); |
| 1430 | 1547 |
| 1548 // Get the elements array of the object. |
| 1549 __ ldr(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); |
| 1550 |
| 1551 // Check that the elements are in fast mode and writable. |
| 1552 __ CheckMap(elements, r0, Heap::kFixedArrayMapRootIndex, &call_builtin, true); |
| 1553 |
| 1554 // Get the array's length into r4 and calculate new length. |
| 1555 __ ldr(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1556 __ sub(r4, r4, Operand(Smi::FromInt(1)), SetCC); |
| 1557 __ b(lt, &return_undefined); |
| 1558 |
| 1559 // Get the last element. |
| 1560 __ LoadRoot(r6, Heap::kTheHoleValueRootIndex); |
| 1561 STATIC_ASSERT(kSmiTagSize == 1); |
| 1562 STATIC_ASSERT(kSmiTag == 0); |
| 1563 // We can't address the last element in one operation. Compute the more |
| 1564 // expensive shift first, and use an offset later on. |
| 1565 __ add(elements, elements, Operand(r4, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 1566 __ ldr(r0, MemOperand(elements, FixedArray::kHeaderSize - kHeapObjectTag)); |
| 1567 __ cmp(r0, r6); |
| 1568 __ b(eq, &call_builtin); |
| 1569 |
| 1570 // Set the array's length. |
| 1571 __ str(r4, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1572 |
| 1573 // Fill with the hole. |
| 1574 __ str(r6, MemOperand(elements, FixedArray::kHeaderSize - kHeapObjectTag)); |
| 1575 __ Drop(argc + 1); |
| 1576 __ Ret(); |
| 1577 |
| 1578 __ bind(&return_undefined); |
| 1579 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 1580 __ Drop(argc + 1); |
| 1581 __ Ret(); |
| 1582 |
| 1583 __ bind(&call_builtin); |
| 1431 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), | 1584 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop), |
| 1432 argc + 1, | 1585 argc + 1, |
| 1433 1); | 1586 1); |
| 1434 | 1587 |
| 1435 // Handle call cache miss. | 1588 // Handle call cache miss. |
| 1436 __ bind(&miss); | 1589 __ bind(&miss); |
| 1437 Object* obj; | 1590 Object* obj; |
| 1438 { MaybeObject* maybe_obj = GenerateMissBranch(); | 1591 { MaybeObject* maybe_obj = GenerateMissBranch(); |
| 1439 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1592 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1440 } | 1593 } |
| (...skipping 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2665 } | 2818 } |
| 2666 | 2819 |
| 2667 | 2820 |
| 2668 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { | 2821 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { |
| 2669 // ----------- S t a t e ------------- | 2822 // ----------- S t a t e ------------- |
| 2670 // -- lr : return address | 2823 // -- lr : return address |
| 2671 // -- r0 : key | 2824 // -- r0 : key |
| 2672 // -- r1 : receiver | 2825 // -- r1 : receiver |
| 2673 // ----------------------------------- | 2826 // ----------------------------------- |
| 2674 Label miss; | 2827 Label miss; |
| 2675 __ IncrementCounter(&Counters::keyed_load_string_length, 1, r1, r3); | 2828 __ IncrementCounter(&Counters::keyed_load_string_length, 1, r2, r3); |
| 2676 | 2829 |
| 2677 // Check the key is the cached one. | 2830 // Check the key is the cached one. |
| 2678 __ cmp(r0, Operand(Handle<String>(name))); | 2831 __ cmp(r0, Operand(Handle<String>(name))); |
| 2679 __ b(ne, &miss); | 2832 __ b(ne, &miss); |
| 2680 | 2833 |
| 2681 GenerateLoadStringLength(masm(), r1, r2, r3, &miss); | 2834 GenerateLoadStringLength(masm(), r1, r2, r3, &miss); |
| 2682 __ bind(&miss); | 2835 __ bind(&miss); |
| 2683 __ DecrementCounter(&Counters::keyed_load_string_length, 1, r1, r3); | 2836 __ DecrementCounter(&Counters::keyed_load_string_length, 1, r2, r3); |
| 2684 | 2837 |
| 2685 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2838 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 2686 | 2839 |
| 2687 return GetCode(CALLBACKS, name); | 2840 return GetCode(CALLBACKS, name); |
| 2688 } | 2841 } |
| 2689 | 2842 |
| 2690 | 2843 |
| 2691 // TODO(1224671): implement the fast case. | |
| 2692 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 2844 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
| 2693 // ----------- S t a t e ------------- | 2845 // ----------- S t a t e ------------- |
| 2694 // -- lr : return address | 2846 // -- lr : return address |
| 2695 // -- r0 : key | 2847 // -- r0 : key |
| 2696 // -- r1 : receiver | 2848 // -- r1 : receiver |
| 2697 // ----------------------------------- | 2849 // ----------------------------------- |
| 2850 Label miss; |
| 2851 |
| 2852 __ IncrementCounter(&Counters::keyed_load_function_prototype, 1, r2, r3); |
| 2853 |
| 2854 // Check the name hasn't changed. |
| 2855 __ cmp(r0, Operand(Handle<String>(name))); |
| 2856 __ b(ne, &miss); |
| 2857 |
| 2858 GenerateLoadFunctionPrototype(masm(), r1, r2, r3, &miss); |
| 2859 __ bind(&miss); |
| 2860 __ DecrementCounter(&Counters::keyed_load_function_prototype, 1, r2, r3); |
| 2698 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2861 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 2699 | 2862 |
| 2700 return GetCode(CALLBACKS, name); | 2863 return GetCode(CALLBACKS, name); |
| 2701 } | 2864 } |
| 2702 | 2865 |
| 2703 | 2866 |
| 2704 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, | 2867 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, |
| 2705 int index, | 2868 int index, |
| 2706 Map* transition, | 2869 Map* transition, |
| 2707 String* name) { | 2870 String* name) { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2880 // Return the generated code. | 3043 // Return the generated code. |
| 2881 return GetCode(); | 3044 return GetCode(); |
| 2882 } | 3045 } |
| 2883 | 3046 |
| 2884 | 3047 |
| 2885 #undef __ | 3048 #undef __ |
| 2886 | 3049 |
| 2887 } } // namespace v8::internal | 3050 } } // namespace v8::internal |
| 2888 | 3051 |
| 2889 #endif // V8_TARGET_ARCH_ARM | 3052 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |