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 |