| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 // If we've skipped any global objects, it's not enough to verify that | 1291 // If we've skipped any global objects, it's not enough to verify that |
| 1292 // their maps haven't changed. We also need to check that the property | 1292 // their maps haven't changed. We also need to check that the property |
| 1293 // cell for the property is still empty. | 1293 // cell for the property is still empty. |
| 1294 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); | 1294 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); |
| 1295 | 1295 |
| 1296 // Return the register containing the holder. | 1296 // Return the register containing the holder. |
| 1297 return reg; | 1297 return reg; |
| 1298 } | 1298 } |
| 1299 | 1299 |
| 1300 | 1300 |
| 1301 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, | 1301 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { |
| 1302 Label* success, | |
| 1303 Label* miss) { | |
| 1304 if (!miss->is_unused()) { | 1302 if (!miss->is_unused()) { |
| 1305 __ b(success); | 1303 Label success; |
| 1304 __ b(&success); |
| 1306 __ bind(miss); | 1305 __ bind(miss); |
| 1307 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1306 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 1307 __ bind(&success); |
| 1308 } | 1308 } |
| 1309 } | 1309 } |
| 1310 | 1310 |
| 1311 | 1311 |
| 1312 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, | 1312 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { |
| 1313 Label* success, | |
| 1314 Label* miss) { | |
| 1315 if (!miss->is_unused()) { | 1313 if (!miss->is_unused()) { |
| 1316 __ b(success); | 1314 Label success; |
| 1315 __ b(&success); |
| 1317 GenerateRestoreName(masm(), miss, name); | 1316 GenerateRestoreName(masm(), miss, name); |
| 1318 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1317 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 1318 __ bind(&success); |
| 1319 } | 1319 } |
| 1320 } | 1320 } |
| 1321 | 1321 |
| 1322 | 1322 |
| 1323 Register LoadStubCompiler::CallbackHandlerFrontend( | 1323 Register LoadStubCompiler::CallbackHandlerFrontend( |
| 1324 Handle<JSObject> object, | 1324 Handle<Object> object, |
| 1325 Register object_reg, | 1325 Register object_reg, |
| 1326 Handle<JSObject> holder, | 1326 Handle<JSObject> holder, |
| 1327 Handle<Name> name, | 1327 Handle<Name> name, |
| 1328 Label* success, | |
| 1329 Handle<Object> callback) { | 1328 Handle<Object> callback) { |
| 1330 Label miss; | 1329 Label miss; |
| 1331 | 1330 |
| 1332 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); | 1331 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); |
| 1333 | 1332 |
| 1334 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1333 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
| 1335 ASSERT(!reg.is(scratch2())); | 1334 ASSERT(!reg.is(scratch2())); |
| 1336 ASSERT(!reg.is(scratch3())); | 1335 ASSERT(!reg.is(scratch3())); |
| 1337 ASSERT(!reg.is(scratch4())); | 1336 ASSERT(!reg.is(scratch4())); |
| 1338 | 1337 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1355 // pointer into the dictionary. Check that the value is the callback. | 1354 // pointer into the dictionary. Check that the value is the callback. |
| 1356 Register pointer = scratch3(); | 1355 Register pointer = scratch3(); |
| 1357 const int kElementsStartOffset = NameDictionary::kHeaderSize + | 1356 const int kElementsStartOffset = NameDictionary::kHeaderSize + |
| 1358 NameDictionary::kElementsStartIndex * kPointerSize; | 1357 NameDictionary::kElementsStartIndex * kPointerSize; |
| 1359 const int kValueOffset = kElementsStartOffset + kPointerSize; | 1358 const int kValueOffset = kElementsStartOffset + kPointerSize; |
| 1360 __ ldr(scratch2(), FieldMemOperand(pointer, kValueOffset)); | 1359 __ ldr(scratch2(), FieldMemOperand(pointer, kValueOffset)); |
| 1361 __ cmp(scratch2(), Operand(callback)); | 1360 __ cmp(scratch2(), Operand(callback)); |
| 1362 __ b(ne, &miss); | 1361 __ b(ne, &miss); |
| 1363 } | 1362 } |
| 1364 | 1363 |
| 1365 HandlerFrontendFooter(name, success, &miss); | 1364 HandlerFrontendFooter(name, &miss); |
| 1366 return reg; | 1365 return reg; |
| 1367 } | 1366 } |
| 1368 | 1367 |
| 1369 | 1368 |
| 1370 void LoadStubCompiler::GenerateLoadField(Register reg, | 1369 void LoadStubCompiler::GenerateLoadField(Register reg, |
| 1371 Handle<JSObject> holder, | 1370 Handle<JSObject> holder, |
| 1372 PropertyIndex field, | 1371 PropertyIndex field, |
| 1373 Representation representation) { | 1372 Representation representation) { |
| 1374 if (!reg.is(receiver())) __ mov(receiver(), reg); | 1373 if (!reg.is(receiver())) __ mov(receiver(), reg); |
| 1375 if (kind() == Code::LOAD_IC) { | 1374 if (kind() == Code::LOAD_IC) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1461 thunk_ref, | 1460 thunk_ref, |
| 1462 r2, | 1461 r2, |
| 1463 kStackUnwindSpace, | 1462 kStackUnwindSpace, |
| 1464 MemOperand(fp, 6 * kPointerSize), | 1463 MemOperand(fp, 6 * kPointerSize), |
| 1465 NULL); | 1464 NULL); |
| 1466 } | 1465 } |
| 1467 | 1466 |
| 1468 | 1467 |
| 1469 void LoadStubCompiler::GenerateLoadInterceptor( | 1468 void LoadStubCompiler::GenerateLoadInterceptor( |
| 1470 Register holder_reg, | 1469 Register holder_reg, |
| 1471 Handle<JSObject> object, | 1470 Handle<Object> object, |
| 1472 Handle<JSObject> interceptor_holder, | 1471 Handle<JSObject> interceptor_holder, |
| 1473 LookupResult* lookup, | 1472 LookupResult* lookup, |
| 1474 Handle<Name> name) { | 1473 Handle<Name> name) { |
| 1475 ASSERT(interceptor_holder->HasNamedInterceptor()); | 1474 ASSERT(interceptor_holder->HasNamedInterceptor()); |
| 1476 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 1475 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); |
| 1477 | 1476 |
| 1478 // So far the most popular follow ups for interceptor loads are FIELD | 1477 // So far the most popular follow ups for interceptor loads are FIELD |
| 1479 // and CALLBACKS, so inline only them, other cases may be added | 1478 // and CALLBACKS, so inline only them, other cases may be added |
| 1480 // later. | 1479 // later. |
| 1481 bool compile_followup_inline = false; | 1480 bool compile_followup_inline = false; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1644 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), | 1643 GenerateFastPropertyLoad(masm(), r1, reg, index.is_inobject(holder), |
| 1645 index.translate(holder), Representation::Tagged()); | 1644 index.translate(holder), Representation::Tagged()); |
| 1646 | 1645 |
| 1647 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 1646 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
| 1648 | 1647 |
| 1649 // Handle call cache miss. | 1648 // Handle call cache miss. |
| 1650 __ bind(&miss); | 1649 __ bind(&miss); |
| 1651 GenerateMissBranch(); | 1650 GenerateMissBranch(); |
| 1652 | 1651 |
| 1653 // Return the generated code. | 1652 // Return the generated code. |
| 1654 return GetCode(Code::FIELD, name); | 1653 return GetCode(Code::FAST, name); |
| 1655 } | 1654 } |
| 1656 | 1655 |
| 1657 | 1656 |
| 1658 Handle<Code> CallStubCompiler::CompileArrayCodeCall( | 1657 Handle<Code> CallStubCompiler::CompileArrayCodeCall( |
| 1659 Handle<Object> object, | 1658 Handle<Object> object, |
| 1660 Handle<JSObject> holder, | 1659 Handle<JSObject> holder, |
| 1661 Handle<Cell> cell, | 1660 Handle<Cell> cell, |
| 1662 Handle<JSFunction> function, | 1661 Handle<JSFunction> function, |
| 1663 Handle<String> name, | 1662 Handle<String> name, |
| 1664 Code::StubType type) { | 1663 Code::StubType type) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1679 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, r3, r0, | 1678 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, r3, r0, |
| 1680 r4, name, &miss); | 1679 r4, name, &miss); |
| 1681 } else { | 1680 } else { |
| 1682 ASSERT(cell->value() == *function); | 1681 ASSERT(cell->value() == *function); |
| 1683 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, | 1682 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, |
| 1684 &miss); | 1683 &miss); |
| 1685 GenerateLoadFunctionFromCell(cell, function, &miss); | 1684 GenerateLoadFunctionFromCell(cell, function, &miss); |
| 1686 } | 1685 } |
| 1687 | 1686 |
| 1688 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); | 1687 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); |
| 1689 site->set_transition_info(Smi::FromInt(GetInitialFastElementsKind())); | 1688 site->SetElementsKind(GetInitialFastElementsKind()); |
| 1690 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); | 1689 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); |
| 1691 __ mov(r0, Operand(argc)); | 1690 __ mov(r0, Operand(argc)); |
| 1692 __ mov(r2, Operand(site_feedback_cell)); | 1691 __ mov(r2, Operand(site_feedback_cell)); |
| 1693 __ mov(r1, Operand(function)); | 1692 __ mov(r1, Operand(function)); |
| 1694 | 1693 |
| 1695 ArrayConstructorStub stub(isolate()); | 1694 ArrayConstructorStub stub(isolate()); |
| 1696 __ TailCallStub(&stub); | 1695 __ TailCallStub(&stub); |
| 1697 | 1696 |
| 1698 __ bind(&miss); | 1697 __ bind(&miss); |
| 1699 GenerateMissBranch(); | 1698 GenerateMissBranch(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1711 Handle<String> name, | 1710 Handle<String> name, |
| 1712 Code::StubType type) { | 1711 Code::StubType type) { |
| 1713 // ----------- S t a t e ------------- | 1712 // ----------- S t a t e ------------- |
| 1714 // -- r2 : name | 1713 // -- r2 : name |
| 1715 // -- lr : return address | 1714 // -- lr : return address |
| 1716 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1715 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1717 // -- ... | 1716 // -- ... |
| 1718 // -- sp[argc * 4] : receiver | 1717 // -- sp[argc * 4] : receiver |
| 1719 // ----------------------------------- | 1718 // ----------------------------------- |
| 1720 | 1719 |
| 1721 // If object is not an array, bail out to regular call. | 1720 // If object is not an array or is observed, bail out to regular call. |
| 1722 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); | 1721 if (!object->IsJSArray() || |
| 1722 !cell.is_null() || |
| 1723 Handle<JSArray>::cast(object)->map()->is_observed()) { |
| 1724 return Handle<Code>::null(); |
| 1725 } |
| 1723 | 1726 |
| 1724 Label miss; | 1727 Label miss; |
| 1725 GenerateNameCheck(name, &miss); | 1728 GenerateNameCheck(name, &miss); |
| 1726 | 1729 |
| 1727 Register receiver = r1; | 1730 Register receiver = r1; |
| 1728 // Get the receiver from the stack | 1731 // Get the receiver from the stack |
| 1729 const int argc = arguments().immediate(); | 1732 const int argc = arguments().immediate(); |
| 1730 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1733 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1731 | 1734 |
| 1732 // Check that the receiver isn't a smi. | 1735 // Check that the receiver isn't a smi. |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1965 Handle<String> name, | 1968 Handle<String> name, |
| 1966 Code::StubType type) { | 1969 Code::StubType type) { |
| 1967 // ----------- S t a t e ------------- | 1970 // ----------- S t a t e ------------- |
| 1968 // -- r2 : name | 1971 // -- r2 : name |
| 1969 // -- lr : return address | 1972 // -- lr : return address |
| 1970 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) | 1973 // -- sp[(argc - n - 1) * 4] : arg[n] (zero-based) |
| 1971 // -- ... | 1974 // -- ... |
| 1972 // -- sp[argc * 4] : receiver | 1975 // -- sp[argc * 4] : receiver |
| 1973 // ----------------------------------- | 1976 // ----------------------------------- |
| 1974 | 1977 |
| 1975 // If object is not an array, bail out to regular call. | 1978 // If object is not an array or is observed, bail out to regular call. |
| 1976 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); | 1979 if (!object->IsJSArray() || |
| 1980 !cell.is_null() || |
| 1981 Handle<JSArray>::cast(object)->map()->is_observed()) { |
| 1982 return Handle<Code>::null(); |
| 1983 } |
| 1977 | 1984 |
| 1978 Label miss, return_undefined, call_builtin; | 1985 Label miss, return_undefined, call_builtin; |
| 1979 Register receiver = r1; | 1986 Register receiver = r1; |
| 1980 Register elements = r3; | 1987 Register elements = r3; |
| 1981 GenerateNameCheck(name, &miss); | 1988 GenerateNameCheck(name, &miss); |
| 1982 | 1989 |
| 1983 // Get the receiver from the stack | 1990 // Get the receiver from the stack |
| 1984 const int argc = arguments().immediate(); | 1991 const int argc = arguments().immediate(); |
| 1985 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); | 1992 __ ldr(receiver, MemOperand(sp, argc * kPointerSize)); |
| 1986 // Check that the receiver isn't a smi. | 1993 // Check that the receiver isn't a smi. |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2532 FreeSpaceForFastApiCall(masm()); | 2539 FreeSpaceForFastApiCall(masm()); |
| 2533 | 2540 |
| 2534 __ bind(&miss_before_stack_reserved); | 2541 __ bind(&miss_before_stack_reserved); |
| 2535 GenerateMissBranch(); | 2542 GenerateMissBranch(); |
| 2536 | 2543 |
| 2537 // Return the generated code. | 2544 // Return the generated code. |
| 2538 return GetCode(function); | 2545 return GetCode(function); |
| 2539 } | 2546 } |
| 2540 | 2547 |
| 2541 | 2548 |
| 2549 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { |
| 2550 Label success; |
| 2551 // Check that the object is a boolean. |
| 2552 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 2553 __ cmp(object, ip); |
| 2554 __ b(eq, &success); |
| 2555 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
| 2556 __ cmp(object, ip); |
| 2557 __ b(ne, miss); |
| 2558 __ bind(&success); |
| 2559 } |
| 2560 |
| 2561 |
| 2542 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, | 2562 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, |
| 2543 Handle<JSObject> holder, | 2563 Handle<JSObject> holder, |
| 2544 Handle<Name> name, | 2564 Handle<Name> name, |
| 2545 CheckType check, | 2565 CheckType check) { |
| 2546 Label* success) { | |
| 2547 // ----------- S t a t e ------------- | 2566 // ----------- S t a t e ------------- |
| 2548 // -- r2 : name | 2567 // -- r2 : name |
| 2549 // -- lr : return address | 2568 // -- lr : return address |
| 2550 // ----------------------------------- | 2569 // ----------------------------------- |
| 2551 Label miss; | 2570 Label miss; |
| 2552 GenerateNameCheck(name, &miss); | 2571 GenerateNameCheck(name, &miss); |
| 2553 | 2572 |
| 2554 // Get the receiver from the stack | 2573 // Get the receiver from the stack |
| 2555 const int argc = arguments().immediate(); | 2574 const int argc = arguments().immediate(); |
| 2556 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2575 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2612 __ bind(&fast); | 2631 __ bind(&fast); |
| 2613 // Check that the maps starting from the prototype haven't changed. | 2632 // Check that the maps starting from the prototype haven't changed. |
| 2614 GenerateDirectLoadGlobalFunctionPrototype( | 2633 GenerateDirectLoadGlobalFunctionPrototype( |
| 2615 masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss); | 2634 masm(), Context::NUMBER_FUNCTION_INDEX, r0, &miss); |
| 2616 CheckPrototypes( | 2635 CheckPrototypes( |
| 2617 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2636 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), |
| 2618 r0, holder, r3, r1, r4, name, &miss); | 2637 r0, holder, r3, r1, r4, name, &miss); |
| 2619 break; | 2638 break; |
| 2620 } | 2639 } |
| 2621 case BOOLEAN_CHECK: { | 2640 case BOOLEAN_CHECK: { |
| 2622 Label fast; | 2641 GenerateBooleanCheck(r1, &miss); |
| 2623 // Check that the object is a boolean. | 2642 |
| 2624 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | |
| 2625 __ cmp(r1, ip); | |
| 2626 __ b(eq, &fast); | |
| 2627 __ LoadRoot(ip, Heap::kFalseValueRootIndex); | |
| 2628 __ cmp(r1, ip); | |
| 2629 __ b(ne, &miss); | |
| 2630 __ bind(&fast); | |
| 2631 // Check that the maps starting from the prototype haven't changed. | 2643 // Check that the maps starting from the prototype haven't changed. |
| 2632 GenerateDirectLoadGlobalFunctionPrototype( | 2644 GenerateDirectLoadGlobalFunctionPrototype( |
| 2633 masm(), Context::BOOLEAN_FUNCTION_INDEX, r0, &miss); | 2645 masm(), Context::BOOLEAN_FUNCTION_INDEX, r0, &miss); |
| 2634 CheckPrototypes( | 2646 CheckPrototypes( |
| 2635 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), | 2647 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), |
| 2636 r0, holder, r3, r1, r4, name, &miss); | 2648 r0, holder, r3, r1, r4, name, &miss); |
| 2637 break; | 2649 break; |
| 2638 } | 2650 } |
| 2639 } | 2651 } |
| 2640 | 2652 |
| 2641 __ b(success); | 2653 Label success; |
| 2654 __ b(&success); |
| 2642 | 2655 |
| 2643 // Handle call cache miss. | 2656 // Handle call cache miss. |
| 2644 __ bind(&miss); | 2657 __ bind(&miss); |
| 2645 GenerateMissBranch(); | 2658 GenerateMissBranch(); |
| 2659 |
| 2660 __ bind(&success); |
| 2646 } | 2661 } |
| 2647 | 2662 |
| 2648 | 2663 |
| 2649 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { | 2664 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { |
| 2650 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2665 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2651 ? CALL_AS_FUNCTION | 2666 ? CALL_AS_FUNCTION |
| 2652 : CALL_AS_METHOD; | 2667 : CALL_AS_METHOD; |
| 2653 ParameterCount expected(function); | 2668 ParameterCount expected(function); |
| 2654 __ InvokeFunction(function, expected, arguments(), | 2669 __ InvokeFunction(function, expected, arguments(), |
| 2655 JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2670 JUMP_FUNCTION, NullCallWrapper(), call_kind); |
| 2656 } | 2671 } |
| 2657 | 2672 |
| 2658 | 2673 |
| 2659 Handle<Code> CallStubCompiler::CompileCallConstant( | 2674 Handle<Code> CallStubCompiler::CompileCallConstant( |
| 2660 Handle<Object> object, | 2675 Handle<Object> object, |
| 2661 Handle<JSObject> holder, | 2676 Handle<JSObject> holder, |
| 2662 Handle<Name> name, | 2677 Handle<Name> name, |
| 2663 CheckType check, | 2678 CheckType check, |
| 2664 Handle<JSFunction> function) { | 2679 Handle<JSFunction> function) { |
| 2665 if (HasCustomCallGenerator(function)) { | 2680 if (HasCustomCallGenerator(function)) { |
| 2666 Handle<Code> code = CompileCustomCall(object, holder, | 2681 Handle<Code> code = CompileCustomCall(object, holder, |
| 2667 Handle<Cell>::null(), | 2682 Handle<Cell>::null(), |
| 2668 function, Handle<String>::cast(name), | 2683 function, Handle<String>::cast(name), |
| 2669 Code::CONSTANT); | 2684 Code::FAST); |
| 2670 // A null handle means bail out to the regular compiler code below. | 2685 // A null handle means bail out to the regular compiler code below. |
| 2671 if (!code.is_null()) return code; | 2686 if (!code.is_null()) return code; |
| 2672 } | 2687 } |
| 2673 | 2688 |
| 2674 Label success; | 2689 CompileHandlerFrontend(object, holder, name, check); |
| 2675 | |
| 2676 CompileHandlerFrontend(object, holder, name, check, &success); | |
| 2677 __ bind(&success); | |
| 2678 CompileHandlerBackend(function); | 2690 CompileHandlerBackend(function); |
| 2679 | 2691 |
| 2680 // Return the generated code. | 2692 // Return the generated code. |
| 2681 return GetCode(function); | 2693 return GetCode(function); |
| 2682 } | 2694 } |
| 2683 | 2695 |
| 2684 | 2696 |
| 2685 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2697 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
| 2686 Handle<JSObject> holder, | 2698 Handle<JSObject> holder, |
| 2687 Handle<Name> name) { | 2699 Handle<Name> name) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2709 // Restore receiver. | 2721 // Restore receiver. |
| 2710 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 2722 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 2711 | 2723 |
| 2712 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); | 2724 GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); |
| 2713 | 2725 |
| 2714 // Handle call cache miss. | 2726 // Handle call cache miss. |
| 2715 __ bind(&miss); | 2727 __ bind(&miss); |
| 2716 GenerateMissBranch(); | 2728 GenerateMissBranch(); |
| 2717 | 2729 |
| 2718 // Return the generated code. | 2730 // Return the generated code. |
| 2719 return GetCode(Code::INTERCEPTOR, name); | 2731 return GetCode(Code::FAST, name); |
| 2720 } | 2732 } |
| 2721 | 2733 |
| 2722 | 2734 |
| 2723 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2735 Handle<Code> CallStubCompiler::CompileCallGlobal( |
| 2724 Handle<JSObject> object, | 2736 Handle<JSObject> object, |
| 2725 Handle<GlobalObject> holder, | 2737 Handle<GlobalObject> holder, |
| 2726 Handle<PropertyCell> cell, | 2738 Handle<PropertyCell> cell, |
| 2727 Handle<JSFunction> function, | 2739 Handle<JSFunction> function, |
| 2728 Handle<Name> name) { | 2740 Handle<Name> name) { |
| 2729 // ----------- S t a t e ------------- | 2741 // ----------- S t a t e ------------- |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2778 // Return the generated code. | 2790 // Return the generated code. |
| 2779 return GetCode(Code::NORMAL, name); | 2791 return GetCode(Code::NORMAL, name); |
| 2780 } | 2792 } |
| 2781 | 2793 |
| 2782 | 2794 |
| 2783 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2795 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2784 Handle<JSObject> object, | 2796 Handle<JSObject> object, |
| 2785 Handle<JSObject> holder, | 2797 Handle<JSObject> holder, |
| 2786 Handle<Name> name, | 2798 Handle<Name> name, |
| 2787 Handle<ExecutableAccessorInfo> callback) { | 2799 Handle<ExecutableAccessorInfo> callback) { |
| 2788 Label success; | 2800 HandlerFrontend(object, receiver(), holder, name); |
| 2789 HandlerFrontend(object, receiver(), holder, name, &success); | |
| 2790 __ bind(&success); | |
| 2791 | 2801 |
| 2792 // Stub never generated for non-global objects that require access checks. | 2802 // Stub never generated for non-global objects that require access checks. |
| 2793 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 2803 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 2794 | 2804 |
| 2795 __ push(receiver()); // receiver | 2805 __ push(receiver()); // receiver |
| 2796 __ mov(ip, Operand(callback)); // callback info | 2806 __ mov(ip, Operand(callback)); // callback info |
| 2797 __ push(ip); | 2807 __ push(ip); |
| 2798 __ mov(ip, Operand(name)); | 2808 __ mov(ip, Operand(name)); |
| 2799 __ Push(ip, value()); | 2809 __ Push(ip, value()); |
| 2800 | 2810 |
| 2801 // Do tail-call to the runtime system. | 2811 // Do tail-call to the runtime system. |
| 2802 ExternalReference store_callback_property = | 2812 ExternalReference store_callback_property = |
| 2803 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 2813 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
| 2804 __ TailCallExternalReference(store_callback_property, 4, 1); | 2814 __ TailCallExternalReference(store_callback_property, 4, 1); |
| 2805 | 2815 |
| 2806 // Return the generated code. | 2816 // Return the generated code. |
| 2807 return GetCode(kind(), Code::CALLBACKS, name); | 2817 return GetCode(kind(), Code::FAST, name); |
| 2808 } | 2818 } |
| 2809 | 2819 |
| 2810 | 2820 |
| 2811 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2821 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
| 2812 Handle<JSObject> object, | 2822 Handle<JSObject> object, |
| 2813 Handle<JSObject> holder, | 2823 Handle<JSObject> holder, |
| 2814 Handle<Name> name, | 2824 Handle<Name> name, |
| 2815 const CallOptimization& call_optimization) { | 2825 const CallOptimization& call_optimization) { |
| 2816 Label success; | 2826 HandlerFrontend(object, receiver(), holder, name); |
| 2817 HandlerFrontend(object, receiver(), holder, name, &success); | |
| 2818 __ bind(&success); | |
| 2819 | 2827 |
| 2820 Register values[] = { value() }; | 2828 Register values[] = { value() }; |
| 2821 GenerateFastApiCall( | 2829 GenerateFastApiCall( |
| 2822 masm(), call_optimization, receiver(), scratch3(), 1, values); | 2830 masm(), call_optimization, receiver(), scratch3(), 1, values); |
| 2823 | 2831 |
| 2824 // Return the generated code. | 2832 // Return the generated code. |
| 2825 return GetCode(kind(), Code::CALLBACKS, name); | 2833 return GetCode(kind(), Code::FAST, name); |
| 2826 } | 2834 } |
| 2827 | 2835 |
| 2828 | 2836 |
| 2829 #undef __ | 2837 #undef __ |
| 2830 #define __ ACCESS_MASM(masm) | 2838 #define __ ACCESS_MASM(masm) |
| 2831 | 2839 |
| 2832 | 2840 |
| 2833 void StoreStubCompiler::GenerateStoreViaSetter( | 2841 void StoreStubCompiler::GenerateStoreViaSetter( |
| 2834 MacroAssembler* masm, | 2842 MacroAssembler* masm, |
| 2835 Handle<JSFunction> setter) { | 2843 Handle<JSFunction> setter) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2898 // Do tail-call to the runtime system. | 2906 // Do tail-call to the runtime system. |
| 2899 ExternalReference store_ic_property = | 2907 ExternalReference store_ic_property = |
| 2900 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); | 2908 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); |
| 2901 __ TailCallExternalReference(store_ic_property, 4, 1); | 2909 __ TailCallExternalReference(store_ic_property, 4, 1); |
| 2902 | 2910 |
| 2903 // Handle store cache miss. | 2911 // Handle store cache miss. |
| 2904 __ bind(&miss); | 2912 __ bind(&miss); |
| 2905 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2913 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2906 | 2914 |
| 2907 // Return the generated code. | 2915 // Return the generated code. |
| 2908 return GetCode(kind(), Code::INTERCEPTOR, name); | 2916 return GetCode(kind(), Code::FAST, name); |
| 2909 } | 2917 } |
| 2910 | 2918 |
| 2911 | 2919 |
| 2912 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2920 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( |
| 2913 Handle<JSObject> object, | 2921 Handle<Object> object, |
| 2914 Handle<JSObject> last, | 2922 Handle<JSObject> last, |
| 2915 Handle<Name> name, | 2923 Handle<Name> name, |
| 2916 Handle<JSGlobalObject> global) { | 2924 Handle<JSGlobalObject> global) { |
| 2917 Label success; | 2925 NonexistentHandlerFrontend(object, last, name, global); |
| 2918 | 2926 |
| 2919 NonexistentHandlerFrontend(object, last, name, &success, global); | |
| 2920 | |
| 2921 __ bind(&success); | |
| 2922 // Return undefined if maps of the full prototype chain are still the | 2927 // Return undefined if maps of the full prototype chain are still the |
| 2923 // same and no global property with this name contains a value. | 2928 // same and no global property with this name contains a value. |
| 2924 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 2929 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 2925 __ Ret(); | 2930 __ Ret(); |
| 2926 | 2931 |
| 2927 // Return the generated code. | 2932 // Return the generated code. |
| 2928 return GetCode(kind(), Code::NONEXISTENT, name); | 2933 return GetCode(kind(), Code::FAST, name); |
| 2929 } | 2934 } |
| 2930 | 2935 |
| 2931 | 2936 |
| 2932 Register* LoadStubCompiler::registers() { | 2937 Register* LoadStubCompiler::registers() { |
| 2933 // receiver, name, scratch1, scratch2, scratch3, scratch4. | 2938 // receiver, name, scratch1, scratch2, scratch3, scratch4. |
| 2934 static Register registers[] = { r0, r2, r3, r1, r4, r5 }; | 2939 static Register registers[] = { r0, r2, r3, r1, r4, r5 }; |
| 2935 return registers; | 2940 return registers; |
| 2936 } | 2941 } |
| 2937 | 2942 |
| 2938 | 2943 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3006 } | 3011 } |
| 3007 __ Ret(); | 3012 __ Ret(); |
| 3008 } | 3013 } |
| 3009 | 3014 |
| 3010 | 3015 |
| 3011 #undef __ | 3016 #undef __ |
| 3012 #define __ ACCESS_MASM(masm()) | 3017 #define __ ACCESS_MASM(masm()) |
| 3013 | 3018 |
| 3014 | 3019 |
| 3015 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 3020 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
| 3016 Handle<JSObject> object, | 3021 Handle<Object> object, |
| 3017 Handle<GlobalObject> global, | 3022 Handle<GlobalObject> global, |
| 3018 Handle<PropertyCell> cell, | 3023 Handle<PropertyCell> cell, |
| 3019 Handle<Name> name, | 3024 Handle<Name> name, |
| 3020 bool is_dont_delete) { | 3025 bool is_dont_delete) { |
| 3021 Label success, miss; | 3026 Label miss; |
| 3022 | 3027 |
| 3023 HandlerFrontendHeader(object, receiver(), global, name, &miss); | 3028 HandlerFrontendHeader(object, receiver(), global, name, &miss); |
| 3024 | 3029 |
| 3025 // Get the value from the cell. | 3030 // Get the value from the cell. |
| 3026 __ mov(r3, Operand(cell)); | 3031 __ mov(r3, Operand(cell)); |
| 3027 __ ldr(r4, FieldMemOperand(r3, Cell::kValueOffset)); | 3032 __ ldr(r4, FieldMemOperand(r3, Cell::kValueOffset)); |
| 3028 | 3033 |
| 3029 // Check for deleted property if property can actually be deleted. | 3034 // Check for deleted property if property can actually be deleted. |
| 3030 if (!is_dont_delete) { | 3035 if (!is_dont_delete) { |
| 3031 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 3036 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 3032 __ cmp(r4, ip); | 3037 __ cmp(r4, ip); |
| 3033 __ b(eq, &miss); | 3038 __ b(eq, &miss); |
| 3034 } | 3039 } |
| 3035 | 3040 |
| 3036 HandlerFrontendFooter(name, &success, &miss); | 3041 HandlerFrontendFooter(name, &miss); |
| 3037 __ bind(&success); | |
| 3038 | 3042 |
| 3039 Counters* counters = isolate()->counters(); | 3043 Counters* counters = isolate()->counters(); |
| 3040 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); | 3044 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); |
| 3041 __ mov(r0, r4); | 3045 __ mov(r0, r4); |
| 3042 __ Ret(); | 3046 __ Ret(); |
| 3043 | 3047 |
| 3044 // Return the generated code. | 3048 // Return the generated code. |
| 3045 return GetCode(kind(), Code::NORMAL, name); | 3049 return GetCode(kind(), Code::NORMAL, name); |
| 3046 } | 3050 } |
| 3047 | 3051 |
| 3048 | 3052 |
| 3049 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( | 3053 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( |
| 3050 MapHandleList* receiver_maps, | 3054 TypeHandleList* types, |
| 3051 CodeHandleList* handlers, | 3055 CodeHandleList* handlers, |
| 3052 Handle<Name> name, | 3056 Handle<Name> name, |
| 3053 Code::StubType type, | 3057 Code::StubType type, |
| 3054 IcCheckType check) { | 3058 IcCheckType check) { |
| 3055 Label miss; | 3059 Label miss; |
| 3056 | 3060 |
| 3057 if (check == PROPERTY) { | 3061 if (check == PROPERTY) { |
| 3058 GenerateNameCheck(name, this->name(), &miss); | 3062 GenerateNameCheck(name, this->name(), &miss); |
| 3059 } | 3063 } |
| 3060 | 3064 |
| 3061 __ JumpIfSmi(receiver(), &miss); | 3065 Label number_case; |
| 3066 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; |
| 3067 __ JumpIfSmi(receiver(), smi_target); |
| 3068 |
| 3062 Register map_reg = scratch1(); | 3069 Register map_reg = scratch1(); |
| 3063 | 3070 |
| 3064 int receiver_count = receiver_maps->length(); | 3071 int receiver_count = types->length(); |
| 3065 int number_of_handled_maps = 0; | 3072 int number_of_handled_maps = 0; |
| 3066 __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); | 3073 __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); |
| 3067 for (int current = 0; current < receiver_count; ++current) { | 3074 for (int current = 0; current < receiver_count; ++current) { |
| 3068 Handle<Map> map = receiver_maps->at(current); | 3075 Handle<Type> type = types->at(current); |
| 3076 Handle<Map> map = IC::TypeToMap(*type, isolate()); |
| 3069 if (!map->is_deprecated()) { | 3077 if (!map->is_deprecated()) { |
| 3070 number_of_handled_maps++; | 3078 number_of_handled_maps++; |
| 3071 __ mov(ip, Operand(receiver_maps->at(current))); | 3079 __ mov(ip, Operand(map)); |
| 3072 __ cmp(map_reg, ip); | 3080 __ cmp(map_reg, ip); |
| 3081 if (type->Is(Type::Number())) { |
| 3082 ASSERT(!number_case.is_unused()); |
| 3083 __ bind(&number_case); |
| 3084 } |
| 3073 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq); | 3085 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq); |
| 3074 } | 3086 } |
| 3075 } | 3087 } |
| 3076 ASSERT(number_of_handled_maps != 0); | 3088 ASSERT(number_of_handled_maps != 0); |
| 3077 | 3089 |
| 3078 __ bind(&miss); | 3090 __ bind(&miss); |
| 3079 TailCallBuiltin(masm(), MissBuiltin(kind())); | 3091 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 3080 | 3092 |
| 3081 // Return the generated code. | 3093 // Return the generated code. |
| 3082 InlineCacheState state = | 3094 InlineCacheState state = |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3121 #define __ ACCESS_MASM(masm) | 3133 #define __ ACCESS_MASM(masm) |
| 3122 | 3134 |
| 3123 | 3135 |
| 3124 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( | 3136 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( |
| 3125 MacroAssembler* masm) { | 3137 MacroAssembler* masm) { |
| 3126 // ---------- S t a t e -------------- | 3138 // ---------- S t a t e -------------- |
| 3127 // -- lr : return address | 3139 // -- lr : return address |
| 3128 // -- r0 : key | 3140 // -- r0 : key |
| 3129 // -- r1 : receiver | 3141 // -- r1 : receiver |
| 3130 // ----------------------------------- | 3142 // ----------------------------------- |
| 3131 Label slow, miss_force_generic; | 3143 Label slow, miss; |
| 3132 | 3144 |
| 3133 Register key = r0; | 3145 Register key = r0; |
| 3134 Register receiver = r1; | 3146 Register receiver = r1; |
| 3135 | 3147 |
| 3136 __ UntagAndJumpIfNotSmi(r2, key, &miss_force_generic); | 3148 __ UntagAndJumpIfNotSmi(r2, key, &miss); |
| 3137 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 3149 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
| 3138 __ LoadFromNumberDictionary(&slow, r4, key, r0, r2, r3, r5); | 3150 __ LoadFromNumberDictionary(&slow, r4, key, r0, r2, r3, r5); |
| 3139 __ Ret(); | 3151 __ Ret(); |
| 3140 | 3152 |
| 3141 __ bind(&slow); | 3153 __ bind(&slow); |
| 3142 __ IncrementCounter( | 3154 __ IncrementCounter( |
| 3143 masm->isolate()->counters()->keyed_load_external_array_slow(), | 3155 masm->isolate()->counters()->keyed_load_external_array_slow(), |
| 3144 1, r2, r3); | 3156 1, r2, r3); |
| 3145 | 3157 |
| 3146 // ---------- S t a t e -------------- | 3158 // ---------- S t a t e -------------- |
| 3147 // -- lr : return address | 3159 // -- lr : return address |
| 3148 // -- r0 : key | 3160 // -- r0 : key |
| 3149 // -- r1 : receiver | 3161 // -- r1 : receiver |
| 3150 // ----------------------------------- | 3162 // ----------------------------------- |
| 3151 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); | 3163 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); |
| 3152 | 3164 |
| 3153 // Miss case, call the runtime. | 3165 // Miss case, call the runtime. |
| 3154 __ bind(&miss_force_generic); | 3166 __ bind(&miss); |
| 3155 | 3167 |
| 3156 // ---------- S t a t e -------------- | 3168 // ---------- S t a t e -------------- |
| 3157 // -- lr : return address | 3169 // -- lr : return address |
| 3158 // -- r0 : key | 3170 // -- r0 : key |
| 3159 // -- r1 : receiver | 3171 // -- r1 : receiver |
| 3160 // ----------------------------------- | 3172 // ----------------------------------- |
| 3161 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); | 3173 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
| 3162 } | 3174 } |
| 3163 | 3175 |
| 3164 | 3176 |
| 3165 #undef __ | 3177 #undef __ |
| 3166 | 3178 |
| 3167 } } // namespace v8::internal | 3179 } } // namespace v8::internal |
| 3168 | 3180 |
| 3169 #endif // V8_TARGET_ARCH_ARM | 3181 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |