| 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 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 Register name, | 708 Register name, |
| 709 Handle<JSObject> holder_obj) { | 709 Handle<JSObject> holder_obj) { |
| 710 __ push(name); | 710 __ push(name); |
| 711 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); | 711 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); |
| 712 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); | 712 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); |
| 713 Register scratch = name; | 713 Register scratch = name; |
| 714 __ li(scratch, Operand(interceptor)); | 714 __ li(scratch, Operand(interceptor)); |
| 715 __ Push(scratch, receiver, holder); | 715 __ Push(scratch, receiver, holder); |
| 716 __ lw(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset)); | 716 __ lw(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset)); |
| 717 __ push(scratch); | 717 __ push(scratch); |
| 718 __ li(scratch, Operand(ExternalReference::isolate_address())); | 718 __ li(scratch, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 719 __ push(scratch); | 719 __ push(scratch); |
| 720 } | 720 } |
| 721 | 721 |
| 722 | 722 |
| 723 static void CompileCallLoadPropertyWithInterceptor( | 723 static void CompileCallLoadPropertyWithInterceptor( |
| 724 MacroAssembler* masm, | 724 MacroAssembler* masm, |
| 725 Register receiver, | 725 Register receiver, |
| 726 Register holder, | 726 Register holder, |
| 727 Register name, | 727 Register name, |
| 728 Handle<JSObject> holder_obj) { | 728 Handle<JSObject> holder_obj) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 // Pass the additional arguments. | 782 // Pass the additional arguments. |
| 783 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 783 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
| 784 Handle<Object> call_data(api_call_info->data(), masm->isolate()); | 784 Handle<Object> call_data(api_call_info->data(), masm->isolate()); |
| 785 if (masm->isolate()->heap()->InNewSpace(*call_data)) { | 785 if (masm->isolate()->heap()->InNewSpace(*call_data)) { |
| 786 __ li(a0, api_call_info); | 786 __ li(a0, api_call_info); |
| 787 __ lw(t2, FieldMemOperand(a0, CallHandlerInfo::kDataOffset)); | 787 __ lw(t2, FieldMemOperand(a0, CallHandlerInfo::kDataOffset)); |
| 788 } else { | 788 } else { |
| 789 __ li(t2, call_data); | 789 __ li(t2, call_data); |
| 790 } | 790 } |
| 791 | 791 |
| 792 __ li(t3, Operand(ExternalReference::isolate_address())); | 792 __ li(t3, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 793 // Store JS function, call data and isolate. | 793 // Store JS function, call data and isolate. |
| 794 __ sw(t1, MemOperand(sp, 1 * kPointerSize)); | 794 __ sw(t1, MemOperand(sp, 1 * kPointerSize)); |
| 795 __ sw(t2, MemOperand(sp, 2 * kPointerSize)); | 795 __ sw(t2, MemOperand(sp, 2 * kPointerSize)); |
| 796 __ sw(t3, MemOperand(sp, 3 * kPointerSize)); | 796 __ sw(t3, MemOperand(sp, 3 * kPointerSize)); |
| 797 | 797 |
| 798 // Prepare arguments. | 798 // Prepare arguments. |
| 799 __ Addu(a2, sp, Operand(3 * kPointerSize)); | 799 __ Addu(a2, sp, Operand(3 * kPointerSize)); |
| 800 | 800 |
| 801 // Allocate the v8::Arguments structure in the arguments' space since | 801 // Allocate the v8::Arguments structure in the arguments' space since |
| 802 // it's not controlled by GC. | 802 // it's not controlled by GC. |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 | 1158 |
| 1159 if (save_at_depth == depth) { | 1159 if (save_at_depth == depth) { |
| 1160 __ sw(reg, MemOperand(sp)); | 1160 __ sw(reg, MemOperand(sp)); |
| 1161 } | 1161 } |
| 1162 | 1162 |
| 1163 // Go to the next object in the prototype chain. | 1163 // Go to the next object in the prototype chain. |
| 1164 current = prototype; | 1164 current = prototype; |
| 1165 } | 1165 } |
| 1166 | 1166 |
| 1167 // Log the check depth. | 1167 // Log the check depth. |
| 1168 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 1168 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1169 | 1169 |
| 1170 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1170 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { |
| 1171 // Check the holder map. | 1171 // Check the holder map. |
| 1172 __ CheckMap(reg, scratch1, Handle<Map>(holder->map()), miss, | 1172 __ CheckMap(reg, scratch1, Handle<Map>(holder->map()), miss, |
| 1173 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); | 1173 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
| 1174 } | 1174 } |
| 1175 | 1175 |
| 1176 // Perform security check for access to the global object. | 1176 // Perform security check for access to the global object. |
| 1177 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1177 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 1178 if (holder->IsJSGlobalProxy()) { | 1178 if (holder->IsJSGlobalProxy()) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 Handle<ExecutableAccessorInfo> callback) { | 1285 Handle<ExecutableAccessorInfo> callback) { |
| 1286 // Build AccessorInfo::args_ list on the stack and push property name below | 1286 // Build AccessorInfo::args_ list on the stack and push property name below |
| 1287 // the exit frame to make GC aware of them and store pointers to them. | 1287 // the exit frame to make GC aware of them and store pointers to them. |
| 1288 __ push(receiver()); | 1288 __ push(receiver()); |
| 1289 __ mov(scratch2(), sp); // scratch2 = AccessorInfo::args_ | 1289 __ mov(scratch2(), sp); // scratch2 = AccessorInfo::args_ |
| 1290 if (heap()->InNewSpace(callback->data())) { | 1290 if (heap()->InNewSpace(callback->data())) { |
| 1291 __ li(scratch3(), callback); | 1291 __ li(scratch3(), callback); |
| 1292 __ lw(scratch3(), FieldMemOperand(scratch3(), | 1292 __ lw(scratch3(), FieldMemOperand(scratch3(), |
| 1293 ExecutableAccessorInfo::kDataOffset)); | 1293 ExecutableAccessorInfo::kDataOffset)); |
| 1294 } else { | 1294 } else { |
| 1295 __ li(scratch3(), Handle<Object>(callback->data(), | 1295 __ li(scratch3(), Handle<Object>(callback->data(), isolate())); |
| 1296 callback->GetIsolate())); | |
| 1297 } | 1296 } |
| 1298 __ Subu(sp, sp, 4 * kPointerSize); | 1297 __ Subu(sp, sp, 4 * kPointerSize); |
| 1299 __ sw(reg, MemOperand(sp, 3 * kPointerSize)); | 1298 __ sw(reg, MemOperand(sp, 3 * kPointerSize)); |
| 1300 __ sw(scratch3(), MemOperand(sp, 2 * kPointerSize)); | 1299 __ sw(scratch3(), MemOperand(sp, 2 * kPointerSize)); |
| 1301 __ li(scratch3(), Operand(ExternalReference::isolate_address())); | 1300 __ li(scratch3(), |
| 1301 Operand(ExternalReference::isolate_address(isolate()))); |
| 1302 __ sw(scratch3(), MemOperand(sp, 1 * kPointerSize)); | 1302 __ sw(scratch3(), MemOperand(sp, 1 * kPointerSize)); |
| 1303 __ sw(name(), MemOperand(sp, 0 * kPointerSize)); | 1303 __ sw(name(), MemOperand(sp, 0 * kPointerSize)); |
| 1304 | 1304 |
| 1305 __ mov(a2, scratch2()); // Saved in case scratch2 == a1. | 1305 __ mov(a2, scratch2()); // Saved in case scratch2 == a1. |
| 1306 __ mov(a1, sp); // a1 (first argument - see note below) = Handle<Name> | 1306 __ mov(a1, sp); // a1 (first argument - see note below) = Handle<Name> |
| 1307 | 1307 |
| 1308 // NOTE: the O32 abi requires a0 to hold a special pointer when returning a | 1308 // NOTE: the O32 abi requires a0 to hold a special pointer when returning a |
| 1309 // struct from the function (which is currently the case). This means we pass | 1309 // struct from the function (which is currently the case). This means we pass |
| 1310 // the arguments in a1-a2 instead of a0-a1. TryCallApiFunctionAndReturn | 1310 // the arguments in a1-a2 instead of a0-a1. TryCallApiFunctionAndReturn |
| 1311 // will handle setting up a0. | 1311 // will handle setting up a0. |
| 1312 | 1312 |
| 1313 const int kApiStackSpace = 1; | 1313 const int kApiStackSpace = 1; |
| 1314 FrameScope frame_scope(masm(), StackFrame::MANUAL); | 1314 FrameScope frame_scope(masm(), StackFrame::MANUAL); |
| 1315 __ EnterExitFrame(false, kApiStackSpace); | 1315 __ EnterExitFrame(false, kApiStackSpace); |
| 1316 | 1316 |
| 1317 // Create AccessorInfo instance on the stack above the exit frame with | 1317 // Create AccessorInfo instance on the stack above the exit frame with |
| 1318 // scratch2 (internal::Object** args_) as the data. | 1318 // scratch2 (internal::Object** args_) as the data. |
| 1319 __ sw(a2, MemOperand(sp, kPointerSize)); | 1319 __ sw(a2, MemOperand(sp, kPointerSize)); |
| 1320 // a2 (second argument - see note above) = AccessorInfo& | 1320 // a2 (second argument - see note above) = AccessorInfo& |
| 1321 __ Addu(a2, sp, kPointerSize); | 1321 __ Addu(a2, sp, kPointerSize); |
| 1322 | 1322 |
| 1323 const int kStackUnwindSpace = 5; | 1323 const int kStackUnwindSpace = 5; |
| 1324 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1324 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 1325 ApiFunction fun(getter_address); | 1325 ApiFunction fun(getter_address); |
| 1326 ExternalReference ref = | 1326 ExternalReference ref = ExternalReference( |
| 1327 ExternalReference(&fun, | 1327 &fun, ExternalReference::DIRECT_GETTER_CALL, isolate()); |
| 1328 ExternalReference::DIRECT_GETTER_CALL, | |
| 1329 masm()->isolate()); | |
| 1330 __ CallApiFunctionAndReturn(ref, kStackUnwindSpace); | 1328 __ CallApiFunctionAndReturn(ref, kStackUnwindSpace); |
| 1331 } | 1329 } |
| 1332 | 1330 |
| 1333 | 1331 |
| 1334 void BaseLoadStubCompiler::GenerateLoadInterceptor( | 1332 void BaseLoadStubCompiler::GenerateLoadInterceptor( |
| 1335 Register holder_reg, | 1333 Register holder_reg, |
| 1336 Handle<JSObject> object, | 1334 Handle<JSObject> object, |
| 1337 Handle<JSObject> interceptor_holder, | 1335 Handle<JSObject> interceptor_holder, |
| 1338 LookupResult* lookup, | 1336 LookupResult* lookup, |
| 1339 Handle<Name> name) { | 1337 Handle<Name> name) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1404 // Leave the internal frame. | 1402 // Leave the internal frame. |
| 1405 } | 1403 } |
| 1406 GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); | 1404 GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); |
| 1407 } else { // !compile_followup_inline | 1405 } else { // !compile_followup_inline |
| 1408 // Call the runtime system to load the interceptor. | 1406 // Call the runtime system to load the interceptor. |
| 1409 // Check that the maps haven't changed. | 1407 // Check that the maps haven't changed. |
| 1410 PushInterceptorArguments(masm(), receiver(), holder_reg, | 1408 PushInterceptorArguments(masm(), receiver(), holder_reg, |
| 1411 this->name(), interceptor_holder); | 1409 this->name(), interceptor_holder); |
| 1412 | 1410 |
| 1413 ExternalReference ref = ExternalReference( | 1411 ExternalReference ref = ExternalReference( |
| 1414 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); | 1412 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); |
| 1415 __ TailCallExternalReference(ref, 6, 1); | 1413 __ TailCallExternalReference(ref, 6, 1); |
| 1416 } | 1414 } |
| 1417 } | 1415 } |
| 1418 | 1416 |
| 1419 | 1417 |
| 1420 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 1418 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
| 1421 if (kind_ == Code::KEYED_CALL_IC) { | 1419 if (kind_ == Code::KEYED_CALL_IC) { |
| 1422 __ Branch(miss, ne, a2, Operand(name)); | 1420 __ Branch(miss, ne, a2, Operand(name)); |
| 1423 } | 1421 } |
| 1424 } | 1422 } |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1714 __ lw(a2, MemOperand(sp, (argc - 1) * kPointerSize)); | 1712 __ lw(a2, MemOperand(sp, (argc - 1) * kPointerSize)); |
| 1715 // Growing elements that are SMI-only requires special handling in case | 1713 // Growing elements that are SMI-only requires special handling in case |
| 1716 // the new element is non-Smi. For now, delegate to the builtin. | 1714 // the new element is non-Smi. For now, delegate to the builtin. |
| 1717 Label no_fast_elements_check; | 1715 Label no_fast_elements_check; |
| 1718 __ JumpIfSmi(a2, &no_fast_elements_check); | 1716 __ JumpIfSmi(a2, &no_fast_elements_check); |
| 1719 __ lw(t3, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1717 __ lw(t3, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| 1720 __ CheckFastObjectElements(t3, t3, &call_builtin); | 1718 __ CheckFastObjectElements(t3, t3, &call_builtin); |
| 1721 __ bind(&no_fast_elements_check); | 1719 __ bind(&no_fast_elements_check); |
| 1722 | 1720 |
| 1723 ExternalReference new_space_allocation_top = | 1721 ExternalReference new_space_allocation_top = |
| 1724 ExternalReference::new_space_allocation_top_address( | 1722 ExternalReference::new_space_allocation_top_address(isolate()); |
| 1725 masm()->isolate()); | |
| 1726 ExternalReference new_space_allocation_limit = | 1723 ExternalReference new_space_allocation_limit = |
| 1727 ExternalReference::new_space_allocation_limit_address( | 1724 ExternalReference::new_space_allocation_limit_address(isolate()); |
| 1728 masm()->isolate()); | |
| 1729 | 1725 |
| 1730 const int kAllocationDelta = 4; | 1726 const int kAllocationDelta = 4; |
| 1731 // Load top and check if it is the end of elements. | 1727 // Load top and check if it is the end of elements. |
| 1732 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); | 1728 __ sll(end_elements, v0, kPointerSizeLog2 - kSmiTagSize); |
| 1733 __ Addu(end_elements, elements, end_elements); | 1729 __ Addu(end_elements, elements, end_elements); |
| 1734 __ Addu(end_elements, end_elements, Operand(kEndElementsOffset)); | 1730 __ Addu(end_elements, end_elements, Operand(kEndElementsOffset)); |
| 1735 __ li(t3, Operand(new_space_allocation_top)); | 1731 __ li(t3, Operand(new_space_allocation_top)); |
| 1736 __ lw(a3, MemOperand(t3)); | 1732 __ lw(a3, MemOperand(t3)); |
| 1737 __ Branch(&call_builtin, ne, end_elements, Operand(a3)); | 1733 __ Branch(&call_builtin, ne, end_elements, Operand(a3)); |
| 1738 | 1734 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1755 // Update elements' and array's sizes. | 1751 // Update elements' and array's sizes. |
| 1756 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1752 __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1757 __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta))); | 1753 __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta))); |
| 1758 __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); | 1754 __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
| 1759 | 1755 |
| 1760 // Elements are in new space, so write barrier is not required. | 1756 // Elements are in new space, so write barrier is not required. |
| 1761 __ Drop(argc + 1); | 1757 __ Drop(argc + 1); |
| 1762 __ Ret(); | 1758 __ Ret(); |
| 1763 } | 1759 } |
| 1764 __ bind(&call_builtin); | 1760 __ bind(&call_builtin); |
| 1765 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1761 __ TailCallExternalReference( |
| 1766 masm()->isolate()), | 1762 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); |
| 1767 argc + 1, | |
| 1768 1); | |
| 1769 } | 1763 } |
| 1770 | 1764 |
| 1771 // Handle call cache miss. | 1765 // Handle call cache miss. |
| 1772 __ bind(&miss); | 1766 __ bind(&miss); |
| 1773 GenerateMissBranch(); | 1767 GenerateMissBranch(); |
| 1774 | 1768 |
| 1775 // Return the generated code. | 1769 // Return the generated code. |
| 1776 return GetCode(function); | 1770 return GetCode(function); |
| 1777 } | 1771 } |
| 1778 | 1772 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1842 __ sw(t2, FieldMemOperand(elements, FixedArray::kHeaderSize)); | 1836 __ sw(t2, FieldMemOperand(elements, FixedArray::kHeaderSize)); |
| 1843 __ Drop(argc + 1); | 1837 __ Drop(argc + 1); |
| 1844 __ Ret(); | 1838 __ Ret(); |
| 1845 | 1839 |
| 1846 __ bind(&return_undefined); | 1840 __ bind(&return_undefined); |
| 1847 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 1841 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
| 1848 __ Drop(argc + 1); | 1842 __ Drop(argc + 1); |
| 1849 __ Ret(); | 1843 __ Ret(); |
| 1850 | 1844 |
| 1851 __ bind(&call_builtin); | 1845 __ bind(&call_builtin); |
| 1852 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, | 1846 __ TailCallExternalReference( |
| 1853 masm()->isolate()), | 1847 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); |
| 1854 argc + 1, | |
| 1855 1); | |
| 1856 | 1848 |
| 1857 // Handle call cache miss. | 1849 // Handle call cache miss. |
| 1858 __ bind(&miss); | 1850 __ bind(&miss); |
| 1859 GenerateMissBranch(); | 1851 GenerateMissBranch(); |
| 1860 | 1852 |
| 1861 // Return the generated code. | 1853 // Return the generated code. |
| 1862 return GetCode(function); | 1854 return GetCode(function); |
| 1863 } | 1855 } |
| 1864 | 1856 |
| 1865 | 1857 |
| (...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2406 // Check that the receiver isn't a smi. | 2398 // Check that the receiver isn't a smi. |
| 2407 if (check != NUMBER_CHECK) { | 2399 if (check != NUMBER_CHECK) { |
| 2408 __ JumpIfSmi(a1, &miss); | 2400 __ JumpIfSmi(a1, &miss); |
| 2409 } | 2401 } |
| 2410 | 2402 |
| 2411 // Make sure that it's okay not to patch the on stack receiver | 2403 // Make sure that it's okay not to patch the on stack receiver |
| 2412 // unless we're doing a receiver map check. | 2404 // unless we're doing a receiver map check. |
| 2413 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2405 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 2414 switch (check) { | 2406 switch (check) { |
| 2415 case RECEIVER_MAP_CHECK: | 2407 case RECEIVER_MAP_CHECK: |
| 2416 __ IncrementCounter(masm()->isolate()->counters()->call_const(), | 2408 __ IncrementCounter(isolate()->counters()->call_const(), 1, a0, a3); |
| 2417 1, a0, a3); | |
| 2418 | 2409 |
| 2419 // Check that the maps haven't changed. | 2410 // Check that the maps haven't changed. |
| 2420 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, | 2411 CheckPrototypes(Handle<JSObject>::cast(object), a1, holder, a0, a3, t0, |
| 2421 name, &miss); | 2412 name, &miss); |
| 2422 | 2413 |
| 2423 // Patch the receiver on the stack with the global proxy if | 2414 // Patch the receiver on the stack with the global proxy if |
| 2424 // necessary. | 2415 // necessary. |
| 2425 if (object->IsGlobalObject()) { | 2416 if (object->IsGlobalObject()) { |
| 2426 __ lw(a3, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); | 2417 __ lw(a3, FieldMemOperand(a1, GlobalObject::kGlobalReceiverOffset)); |
| 2427 __ sw(a3, MemOperand(sp, argc * kPointerSize)); | 2418 __ sw(a3, MemOperand(sp, argc * kPointerSize)); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2598 // necessary. | 2589 // necessary. |
| 2599 if (object->IsGlobalObject()) { | 2590 if (object->IsGlobalObject()) { |
| 2600 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); | 2591 __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); |
| 2601 __ sw(a3, MemOperand(sp, argc * kPointerSize)); | 2592 __ sw(a3, MemOperand(sp, argc * kPointerSize)); |
| 2602 } | 2593 } |
| 2603 | 2594 |
| 2604 // Set up the context (function already in r1). | 2595 // Set up the context (function already in r1). |
| 2605 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 2596 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
| 2606 | 2597 |
| 2607 // Jump to the cached code (tail call). | 2598 // Jump to the cached code (tail call). |
| 2608 Counters* counters = masm()->isolate()->counters(); | 2599 Counters* counters = isolate()->counters(); |
| 2609 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); | 2600 __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); |
| 2610 ParameterCount expected(function->shared()->formal_parameter_count()); | 2601 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 2611 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2602 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2612 ? CALL_AS_FUNCTION | 2603 ? CALL_AS_FUNCTION |
| 2613 : CALL_AS_METHOD; | 2604 : CALL_AS_METHOD; |
| 2614 // We call indirectly through the code field in the function to | 2605 // We call indirectly through the code field in the function to |
| 2615 // allow recompilation to take effect without changing any of the | 2606 // allow recompilation to take effect without changing any of the |
| 2616 // call sites. | 2607 // call sites. |
| 2617 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 2608 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 2618 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, | 2609 __ InvokeCode(a3, expected, arguments(), JUMP_FUNCTION, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2642 // Stub never generated for non-global objects that require access | 2633 // Stub never generated for non-global objects that require access |
| 2643 // checks. | 2634 // checks. |
| 2644 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 2635 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 2645 | 2636 |
| 2646 __ push(receiver()); // Receiver. | 2637 __ push(receiver()); // Receiver. |
| 2647 __ li(at, Operand(callback)); // Callback info. | 2638 __ li(at, Operand(callback)); // Callback info. |
| 2648 __ Push(at, this->name(), value()); | 2639 __ Push(at, this->name(), value()); |
| 2649 | 2640 |
| 2650 // Do tail-call to the runtime system. | 2641 // Do tail-call to the runtime system. |
| 2651 ExternalReference store_callback_property = | 2642 ExternalReference store_callback_property = |
| 2652 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), | 2643 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
| 2653 masm()->isolate()); | |
| 2654 __ TailCallExternalReference(store_callback_property, 4, 1); | 2644 __ TailCallExternalReference(store_callback_property, 4, 1); |
| 2655 | 2645 |
| 2656 // Handle store cache miss. | 2646 // Handle store cache miss. |
| 2657 __ bind(&miss); | 2647 __ bind(&miss); |
| 2658 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2648 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2659 | 2649 |
| 2660 // Return the generated code. | 2650 // Return the generated code. |
| 2661 return GetICCode(kind(), Code::CALLBACKS, name); | 2651 return GetICCode(kind(), Code::CALLBACKS, name); |
| 2662 } | 2652 } |
| 2663 | 2653 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2726 // checks. | 2716 // checks. |
| 2727 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 2717 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
| 2728 | 2718 |
| 2729 __ Push(receiver(), this->name(), value()); | 2719 __ Push(receiver(), this->name(), value()); |
| 2730 | 2720 |
| 2731 __ li(scratch1(), Operand(Smi::FromInt(strict_mode()))); | 2721 __ li(scratch1(), Operand(Smi::FromInt(strict_mode()))); |
| 2732 __ push(scratch1()); // strict mode | 2722 __ push(scratch1()); // strict mode |
| 2733 | 2723 |
| 2734 // Do tail-call to the runtime system. | 2724 // Do tail-call to the runtime system. |
| 2735 ExternalReference store_ic_property = | 2725 ExternalReference store_ic_property = |
| 2736 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), | 2726 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); |
| 2737 masm()->isolate()); | |
| 2738 __ TailCallExternalReference(store_ic_property, 4, 1); | 2727 __ TailCallExternalReference(store_ic_property, 4, 1); |
| 2739 | 2728 |
| 2740 // Handle store cache miss. | 2729 // Handle store cache miss. |
| 2741 __ bind(&miss); | 2730 __ bind(&miss); |
| 2742 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2731 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2743 | 2732 |
| 2744 // Return the generated code. | 2733 // Return the generated code. |
| 2745 return GetICCode(kind(), Code::INTERCEPTOR, name); | 2734 return GetICCode(kind(), Code::INTERCEPTOR, name); |
| 2746 } | 2735 } |
| 2747 | 2736 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2765 __ lw(scratch3(), | 2754 __ lw(scratch3(), |
| 2766 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); | 2755 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); |
| 2767 __ Branch(&miss, eq, scratch3(), Operand(scratch2())); | 2756 __ Branch(&miss, eq, scratch3(), Operand(scratch2())); |
| 2768 | 2757 |
| 2769 // Store the value in the cell. | 2758 // Store the value in the cell. |
| 2770 __ sw(value(), | 2759 __ sw(value(), |
| 2771 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); | 2760 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); |
| 2772 __ mov(v0, a0); // Stored value must be returned in v0. | 2761 __ mov(v0, a0); // Stored value must be returned in v0. |
| 2773 // Cells are always rescanned, so no write barrier here. | 2762 // Cells are always rescanned, so no write barrier here. |
| 2774 | 2763 |
| 2775 Counters* counters = masm()->isolate()->counters(); | 2764 Counters* counters = isolate()->counters(); |
| 2776 __ IncrementCounter( | 2765 __ IncrementCounter( |
| 2777 counters->named_store_global_inline(), 1, scratch1(), scratch2()); | 2766 counters->named_store_global_inline(), 1, scratch1(), scratch2()); |
| 2778 __ Ret(); | 2767 __ Ret(); |
| 2779 | 2768 |
| 2780 // Handle store cache miss. | 2769 // Handle store cache miss. |
| 2781 __ bind(&miss); | 2770 __ bind(&miss); |
| 2782 __ IncrementCounter( | 2771 __ IncrementCounter( |
| 2783 counters->named_store_global_inline_miss(), 1, scratch1(), scratch2()); | 2772 counters->named_store_global_inline_miss(), 1, scratch1(), scratch2()); |
| 2784 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2773 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2785 | 2774 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2905 | 2894 |
| 2906 // Check for deleted property if property can actually be deleted. | 2895 // Check for deleted property if property can actually be deleted. |
| 2907 if (!is_dont_delete) { | 2896 if (!is_dont_delete) { |
| 2908 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 2897 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 2909 __ Branch(&miss, eq, t0, Operand(at)); | 2898 __ Branch(&miss, eq, t0, Operand(at)); |
| 2910 } | 2899 } |
| 2911 | 2900 |
| 2912 HandlerFrontendFooter(&success, &miss); | 2901 HandlerFrontendFooter(&success, &miss); |
| 2913 __ bind(&success); | 2902 __ bind(&success); |
| 2914 | 2903 |
| 2915 Counters* counters = masm()->isolate()->counters(); | 2904 Counters* counters = isolate()->counters(); |
| 2916 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); | 2905 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); |
| 2917 __ mov(v0, t0); | 2906 __ mov(v0, t0); |
| 2918 __ Ret(); | 2907 __ Ret(); |
| 2919 | 2908 |
| 2920 // Return the generated code. | 2909 // Return the generated code. |
| 2921 return GetICCode(kind(), Code::NORMAL, name); | 2910 return GetICCode(kind(), Code::NORMAL, name); |
| 2922 } | 2911 } |
| 2923 | 2912 |
| 2924 | 2913 |
| 2925 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( | 2914 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3083 __ sw(a2, MemOperand(t5)); | 3072 __ sw(a2, MemOperand(t5)); |
| 3084 __ Addu(t5, t5, kPointerSize); | 3073 __ Addu(t5, t5, kPointerSize); |
| 3085 __ jmp(&next); | 3074 __ jmp(&next); |
| 3086 __ bind(¬_passed); | 3075 __ bind(¬_passed); |
| 3087 // Set the property to undefined. | 3076 // Set the property to undefined. |
| 3088 __ sw(t7, MemOperand(t5)); | 3077 __ sw(t7, MemOperand(t5)); |
| 3089 __ Addu(t5, t5, Operand(kPointerSize)); | 3078 __ Addu(t5, t5, Operand(kPointerSize)); |
| 3090 __ bind(&next); | 3079 __ bind(&next); |
| 3091 } else { | 3080 } else { |
| 3092 // Set the property to the constant value. | 3081 // Set the property to the constant value. |
| 3093 Handle<Object> constant(shared->GetThisPropertyAssignmentConstant(i), | 3082 Handle<Object> constant( |
| 3094 masm()->isolate()); | 3083 shared->GetThisPropertyAssignmentConstant(i), isolate()); |
| 3095 __ li(a2, Operand(constant)); | 3084 __ li(a2, Operand(constant)); |
| 3096 __ sw(a2, MemOperand(t5)); | 3085 __ sw(a2, MemOperand(t5)); |
| 3097 __ Addu(t5, t5, kPointerSize); | 3086 __ Addu(t5, t5, kPointerSize); |
| 3098 } | 3087 } |
| 3099 } | 3088 } |
| 3100 | 3089 |
| 3101 // Fill the unused in-object property fields with undefined. | 3090 // Fill the unused in-object property fields with undefined. |
| 3102 for (int i = shared->this_property_assignments_count(); | 3091 for (int i = shared->this_property_assignments_count(); |
| 3103 i < function->initial_map()->inobject_properties(); | 3092 i < function->initial_map()->inobject_properties(); |
| 3104 i++) { | 3093 i++) { |
| 3105 __ sw(t7, MemOperand(t5)); | 3094 __ sw(t7, MemOperand(t5)); |
| 3106 __ Addu(t5, t5, kPointerSize); | 3095 __ Addu(t5, t5, kPointerSize); |
| 3107 } | 3096 } |
| 3108 | 3097 |
| 3109 // a0: argc | 3098 // a0: argc |
| 3110 // t4: JSObject (not tagged) | 3099 // t4: JSObject (not tagged) |
| 3111 // Move argc to a1 and the JSObject to return to v0 and tag it. | 3100 // Move argc to a1 and the JSObject to return to v0 and tag it. |
| 3112 __ mov(a1, a0); | 3101 __ mov(a1, a0); |
| 3113 __ mov(v0, t4); | 3102 __ mov(v0, t4); |
| 3114 __ Or(v0, v0, Operand(kHeapObjectTag)); | 3103 __ Or(v0, v0, Operand(kHeapObjectTag)); |
| 3115 | 3104 |
| 3116 // v0: JSObject | 3105 // v0: JSObject |
| 3117 // a1: argc | 3106 // a1: argc |
| 3118 // Remove caller arguments and receiver from the stack and return. | 3107 // Remove caller arguments and receiver from the stack and return. |
| 3119 __ sll(t0, a1, kPointerSizeLog2); | 3108 __ sll(t0, a1, kPointerSizeLog2); |
| 3120 __ Addu(sp, sp, t0); | 3109 __ Addu(sp, sp, t0); |
| 3121 __ Addu(sp, sp, Operand(kPointerSize)); | 3110 __ Addu(sp, sp, Operand(kPointerSize)); |
| 3122 Counters* counters = masm()->isolate()->counters(); | 3111 Counters* counters = isolate()->counters(); |
| 3123 __ IncrementCounter(counters->constructed_objects(), 1, a1, a2); | 3112 __ IncrementCounter(counters->constructed_objects(), 1, a1, a2); |
| 3124 __ IncrementCounter(counters->constructed_objects_stub(), 1, a1, a2); | 3113 __ IncrementCounter(counters->constructed_objects_stub(), 1, a1, a2); |
| 3125 __ Ret(); | 3114 __ Ret(); |
| 3126 | 3115 |
| 3127 // Jump to the generic stub in case the specialized code cannot handle the | 3116 // Jump to the generic stub in case the specialized code cannot handle the |
| 3128 // construction. | 3117 // construction. |
| 3129 __ bind(&generic_stub_call); | 3118 __ bind(&generic_stub_call); |
| 3130 Handle<Code> generic_construct_stub = | 3119 Handle<Code> generic_construct_stub = |
| 3131 masm()->isolate()->builtins()->JSConstructStubGeneric(); | 3120 isolate()->builtins()->JSConstructStubGeneric(); |
| 3132 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); | 3121 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); |
| 3133 | 3122 |
| 3134 // Return the generated code. | 3123 // Return the generated code. |
| 3135 return GetCode(); | 3124 return GetCode(); |
| 3136 } | 3125 } |
| 3137 | 3126 |
| 3138 | 3127 |
| 3139 #undef __ | 3128 #undef __ |
| 3140 #define __ ACCESS_MASM(masm) | 3129 #define __ ACCESS_MASM(masm) |
| 3141 | 3130 |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3745 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3734 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
| 3746 } | 3735 } |
| 3747 } | 3736 } |
| 3748 | 3737 |
| 3749 | 3738 |
| 3750 #undef __ | 3739 #undef __ |
| 3751 | 3740 |
| 3752 } } // namespace v8::internal | 3741 } } // namespace v8::internal |
| 3753 | 3742 |
| 3754 #endif // V8_TARGET_ARCH_MIPS | 3743 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |