| 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 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 __ push(name); | 719 __ push(name); |
| 720 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); | 720 Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); |
| 721 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); | 721 ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); |
| 722 Register scratch = name; | 722 Register scratch = name; |
| 723 __ mov(scratch, Operand(interceptor)); | 723 __ mov(scratch, Operand(interceptor)); |
| 724 __ push(scratch); | 724 __ push(scratch); |
| 725 __ push(receiver); | 725 __ push(receiver); |
| 726 __ push(holder); | 726 __ push(holder); |
| 727 __ ldr(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset)); | 727 __ ldr(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset)); |
| 728 __ push(scratch); | 728 __ push(scratch); |
| 729 __ mov(scratch, Operand(ExternalReference::isolate_address())); | 729 __ mov(scratch, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 730 __ push(scratch); | 730 __ push(scratch); |
| 731 } | 731 } |
| 732 | 732 |
| 733 | 733 |
| 734 static void CompileCallLoadPropertyWithInterceptor( | 734 static void CompileCallLoadPropertyWithInterceptor( |
| 735 MacroAssembler* masm, | 735 MacroAssembler* masm, |
| 736 Register receiver, | 736 Register receiver, |
| 737 Register holder, | 737 Register holder, |
| 738 Register name, | 738 Register name, |
| 739 Handle<JSObject> holder_obj) { | 739 Handle<JSObject> holder_obj) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 | 791 |
| 792 // Pass the additional arguments. | 792 // Pass the additional arguments. |
| 793 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 793 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
| 794 Handle<Object> call_data(api_call_info->data(), masm->isolate()); | 794 Handle<Object> call_data(api_call_info->data(), masm->isolate()); |
| 795 if (masm->isolate()->heap()->InNewSpace(*call_data)) { | 795 if (masm->isolate()->heap()->InNewSpace(*call_data)) { |
| 796 __ Move(r0, api_call_info); | 796 __ Move(r0, api_call_info); |
| 797 __ ldr(r6, FieldMemOperand(r0, CallHandlerInfo::kDataOffset)); | 797 __ ldr(r6, FieldMemOperand(r0, CallHandlerInfo::kDataOffset)); |
| 798 } else { | 798 } else { |
| 799 __ Move(r6, call_data); | 799 __ Move(r6, call_data); |
| 800 } | 800 } |
| 801 __ mov(r7, Operand(ExternalReference::isolate_address())); | 801 __ mov(r7, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 802 // Store JS function, call data and isolate. | 802 // Store JS function, call data and isolate. |
| 803 __ stm(ib, sp, r5.bit() | r6.bit() | r7.bit()); | 803 __ stm(ib, sp, r5.bit() | r6.bit() | r7.bit()); |
| 804 | 804 |
| 805 // Prepare arguments. | 805 // Prepare arguments. |
| 806 __ add(r2, sp, Operand(3 * kPointerSize)); | 806 __ add(r2, sp, Operand(3 * kPointerSize)); |
| 807 | 807 |
| 808 // Allocate the v8::Arguments structure in the arguments' space since | 808 // Allocate the v8::Arguments structure in the arguments' space since |
| 809 // it's not controlled by GC. | 809 // it's not controlled by GC. |
| 810 const int kApiStackSpace = 4; | 810 const int kApiStackSpace = 4; |
| 811 | 811 |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 | 1160 |
| 1161 if (save_at_depth == depth) { | 1161 if (save_at_depth == depth) { |
| 1162 __ str(reg, MemOperand(sp)); | 1162 __ str(reg, MemOperand(sp)); |
| 1163 } | 1163 } |
| 1164 | 1164 |
| 1165 // Go to the next object in the prototype chain. | 1165 // Go to the next object in the prototype chain. |
| 1166 current = prototype; | 1166 current = prototype; |
| 1167 } | 1167 } |
| 1168 | 1168 |
| 1169 // Log the check depth. | 1169 // Log the check depth. |
| 1170 LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); | 1170 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); |
| 1171 | 1171 |
| 1172 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1172 if (!holder.is_identical_to(first) || check == CHECK_ALL_MAPS) { |
| 1173 // Check the holder map. | 1173 // Check the holder map. |
| 1174 __ CheckMap(reg, scratch1, Handle<Map>(holder->map()), miss, | 1174 __ CheckMap(reg, scratch1, Handle<Map>(holder->map()), miss, |
| 1175 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); | 1175 DONT_DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); |
| 1176 } | 1176 } |
| 1177 | 1177 |
| 1178 // Perform security check for access to the global object. | 1178 // Perform security check for access to the global object. |
| 1179 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 1179 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 1180 if (holder->IsJSGlobalProxy()) { | 1180 if (holder->IsJSGlobalProxy()) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 Handle<ExecutableAccessorInfo> callback) { | 1288 Handle<ExecutableAccessorInfo> callback) { |
| 1289 // Build AccessorInfo::args_ list on the stack and push property name below | 1289 // Build AccessorInfo::args_ list on the stack and push property name below |
| 1290 // the exit frame to make GC aware of them and store pointers to them. | 1290 // the exit frame to make GC aware of them and store pointers to them. |
| 1291 __ push(receiver()); | 1291 __ push(receiver()); |
| 1292 __ mov(scratch2(), sp); // scratch2 = AccessorInfo::args_ | 1292 __ mov(scratch2(), sp); // scratch2 = AccessorInfo::args_ |
| 1293 if (heap()->InNewSpace(callback->data())) { | 1293 if (heap()->InNewSpace(callback->data())) { |
| 1294 __ Move(scratch3(), callback); | 1294 __ Move(scratch3(), callback); |
| 1295 __ ldr(scratch3(), FieldMemOperand(scratch3(), | 1295 __ ldr(scratch3(), FieldMemOperand(scratch3(), |
| 1296 ExecutableAccessorInfo::kDataOffset)); | 1296 ExecutableAccessorInfo::kDataOffset)); |
| 1297 } else { | 1297 } else { |
| 1298 __ Move(scratch3(), Handle<Object>(callback->data(), | 1298 __ Move(scratch3(), Handle<Object>(callback->data(), isolate())); |
| 1299 callback->GetIsolate())); | |
| 1300 } | 1299 } |
| 1301 __ Push(reg, scratch3()); | 1300 __ Push(reg, scratch3()); |
| 1302 __ mov(scratch3(), Operand(ExternalReference::isolate_address())); | 1301 __ mov(scratch3(), |
| 1302 Operand(ExternalReference::isolate_address(isolate()))); |
| 1303 __ Push(scratch3(), name()); | 1303 __ Push(scratch3(), name()); |
| 1304 __ mov(r0, sp); // r0 = Handle<Name> | 1304 __ mov(r0, sp); // r0 = Handle<Name> |
| 1305 | 1305 |
| 1306 const int kApiStackSpace = 1; | 1306 const int kApiStackSpace = 1; |
| 1307 FrameScope frame_scope(masm(), StackFrame::MANUAL); | 1307 FrameScope frame_scope(masm(), StackFrame::MANUAL); |
| 1308 __ EnterExitFrame(false, kApiStackSpace); | 1308 __ EnterExitFrame(false, kApiStackSpace); |
| 1309 | 1309 |
| 1310 // Create AccessorInfo instance on the stack above the exit frame with | 1310 // Create AccessorInfo instance on the stack above the exit frame with |
| 1311 // scratch2 (internal::Object** args_) as the data. | 1311 // scratch2 (internal::Object** args_) as the data. |
| 1312 __ str(scratch2(), MemOperand(sp, 1 * kPointerSize)); | 1312 __ str(scratch2(), MemOperand(sp, 1 * kPointerSize)); |
| 1313 __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& | 1313 __ add(r1, sp, Operand(1 * kPointerSize)); // r1 = AccessorInfo& |
| 1314 | 1314 |
| 1315 const int kStackUnwindSpace = 5; | 1315 const int kStackUnwindSpace = 5; |
| 1316 Address getter_address = v8::ToCData<Address>(callback->getter()); | 1316 Address getter_address = v8::ToCData<Address>(callback->getter()); |
| 1317 ApiFunction fun(getter_address); | 1317 ApiFunction fun(getter_address); |
| 1318 ExternalReference ref = | 1318 ExternalReference ref = ExternalReference( |
| 1319 ExternalReference(&fun, | 1319 &fun, ExternalReference::DIRECT_GETTER_CALL, isolate()); |
| 1320 ExternalReference::DIRECT_GETTER_CALL, | |
| 1321 masm()->isolate()); | |
| 1322 __ CallApiFunctionAndReturn(ref, kStackUnwindSpace); | 1320 __ CallApiFunctionAndReturn(ref, kStackUnwindSpace); |
| 1323 } | 1321 } |
| 1324 | 1322 |
| 1325 | 1323 |
| 1326 void BaseLoadStubCompiler::GenerateLoadInterceptor( | 1324 void BaseLoadStubCompiler::GenerateLoadInterceptor( |
| 1327 Register holder_reg, | 1325 Register holder_reg, |
| 1328 Handle<JSObject> object, | 1326 Handle<JSObject> object, |
| 1329 Handle<JSObject> interceptor_holder, | 1327 Handle<JSObject> interceptor_holder, |
| 1330 LookupResult* lookup, | 1328 LookupResult* lookup, |
| 1331 Handle<Name> name) { | 1329 Handle<Name> name) { |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1399 | 1397 |
| 1400 GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); | 1398 GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); |
| 1401 } else { // !compile_followup_inline | 1399 } else { // !compile_followup_inline |
| 1402 // Call the runtime system to load the interceptor. | 1400 // Call the runtime system to load the interceptor. |
| 1403 // Check that the maps haven't changed. | 1401 // Check that the maps haven't changed. |
| 1404 PushInterceptorArguments(masm(), receiver(), holder_reg, | 1402 PushInterceptorArguments(masm(), receiver(), holder_reg, |
| 1405 this->name(), interceptor_holder); | 1403 this->name(), interceptor_holder); |
| 1406 | 1404 |
| 1407 ExternalReference ref = | 1405 ExternalReference ref = |
| 1408 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1406 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), |
| 1409 masm()->isolate()); | 1407 isolate()); |
| 1410 __ TailCallExternalReference(ref, 6, 1); | 1408 __ TailCallExternalReference(ref, 6, 1); |
| 1411 } | 1409 } |
| 1412 } | 1410 } |
| 1413 | 1411 |
| 1414 | 1412 |
| 1415 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { | 1413 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
| 1416 if (kind_ == Code::KEYED_CALL_IC) { | 1414 if (kind_ == Code::KEYED_CALL_IC) { |
| 1417 __ cmp(r2, Operand(name)); | 1415 __ cmp(r2, Operand(name)); |
| 1418 __ b(ne, miss); | 1416 __ b(ne, miss); |
| 1419 } | 1417 } |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1709 | 1707 |
| 1710 __ ldr(r2, MemOperand(sp, (argc - 1) * kPointerSize)); | 1708 __ ldr(r2, MemOperand(sp, (argc - 1) * kPointerSize)); |
| 1711 // Growing elements that are SMI-only requires special handling in case | 1709 // Growing elements that are SMI-only requires special handling in case |
| 1712 // the new element is non-Smi. For now, delegate to the builtin. | 1710 // the new element is non-Smi. For now, delegate to the builtin. |
| 1713 Label no_fast_elements_check; | 1711 Label no_fast_elements_check; |
| 1714 __ JumpIfSmi(r2, &no_fast_elements_check); | 1712 __ JumpIfSmi(r2, &no_fast_elements_check); |
| 1715 __ ldr(r7, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1713 __ ldr(r7, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
| 1716 __ CheckFastObjectElements(r7, r7, &call_builtin); | 1714 __ CheckFastObjectElements(r7, r7, &call_builtin); |
| 1717 __ bind(&no_fast_elements_check); | 1715 __ bind(&no_fast_elements_check); |
| 1718 | 1716 |
| 1719 Isolate* isolate = masm()->isolate(); | |
| 1720 ExternalReference new_space_allocation_top = | 1717 ExternalReference new_space_allocation_top = |
| 1721 ExternalReference::new_space_allocation_top_address(isolate); | 1718 ExternalReference::new_space_allocation_top_address(isolate()); |
| 1722 ExternalReference new_space_allocation_limit = | 1719 ExternalReference new_space_allocation_limit = |
| 1723 ExternalReference::new_space_allocation_limit_address(isolate); | 1720 ExternalReference::new_space_allocation_limit_address(isolate()); |
| 1724 | 1721 |
| 1725 const int kAllocationDelta = 4; | 1722 const int kAllocationDelta = 4; |
| 1726 // Load top and check if it is the end of elements. | 1723 // Load top and check if it is the end of elements. |
| 1727 __ add(end_elements, elements, | 1724 __ add(end_elements, elements, |
| 1728 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); | 1725 Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 1729 __ add(end_elements, end_elements, Operand(kEndElementsOffset)); | 1726 __ add(end_elements, end_elements, Operand(kEndElementsOffset)); |
| 1730 __ mov(r7, Operand(new_space_allocation_top)); | 1727 __ mov(r7, Operand(new_space_allocation_top)); |
| 1731 __ ldr(r3, MemOperand(r7)); | 1728 __ ldr(r3, MemOperand(r7)); |
| 1732 __ cmp(end_elements, r3); | 1729 __ cmp(end_elements, r3); |
| 1733 __ b(ne, &call_builtin); | 1730 __ b(ne, &call_builtin); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1752 // Update elements' and array's sizes. | 1749 // Update elements' and array's sizes. |
| 1753 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); | 1750 __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset)); |
| 1754 __ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta))); | 1751 __ add(r4, r4, Operand(Smi::FromInt(kAllocationDelta))); |
| 1755 __ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); | 1752 __ str(r4, FieldMemOperand(elements, FixedArray::kLengthOffset)); |
| 1756 | 1753 |
| 1757 // Elements are in new space, so write barrier is not required. | 1754 // Elements are in new space, so write barrier is not required. |
| 1758 __ Drop(argc + 1); | 1755 __ Drop(argc + 1); |
| 1759 __ Ret(); | 1756 __ Ret(); |
| 1760 } | 1757 } |
| 1761 __ bind(&call_builtin); | 1758 __ bind(&call_builtin); |
| 1762 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, | 1759 __ TailCallExternalReference( |
| 1763 masm()->isolate()), | 1760 ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); |
| 1764 argc + 1, | |
| 1765 1); | |
| 1766 } | 1761 } |
| 1767 | 1762 |
| 1768 // Handle call cache miss. | 1763 // Handle call cache miss. |
| 1769 __ bind(&miss); | 1764 __ bind(&miss); |
| 1770 GenerateMissBranch(); | 1765 GenerateMissBranch(); |
| 1771 | 1766 |
| 1772 // Return the generated code. | 1767 // Return the generated code. |
| 1773 return GetCode(function); | 1768 return GetCode(function); |
| 1774 } | 1769 } |
| 1775 | 1770 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1839 __ str(r6, FieldMemOperand(elements, FixedArray::kHeaderSize)); | 1834 __ str(r6, FieldMemOperand(elements, FixedArray::kHeaderSize)); |
| 1840 __ Drop(argc + 1); | 1835 __ Drop(argc + 1); |
| 1841 __ Ret(); | 1836 __ Ret(); |
| 1842 | 1837 |
| 1843 __ bind(&return_undefined); | 1838 __ bind(&return_undefined); |
| 1844 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); | 1839 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
| 1845 __ Drop(argc + 1); | 1840 __ Drop(argc + 1); |
| 1846 __ Ret(); | 1841 __ Ret(); |
| 1847 | 1842 |
| 1848 __ bind(&call_builtin); | 1843 __ bind(&call_builtin); |
| 1849 __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPop, | 1844 __ TailCallExternalReference( |
| 1850 masm()->isolate()), | 1845 ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); |
| 1851 argc + 1, | |
| 1852 1); | |
| 1853 | 1846 |
| 1854 // Handle call cache miss. | 1847 // Handle call cache miss. |
| 1855 __ bind(&miss); | 1848 __ bind(&miss); |
| 1856 GenerateMissBranch(); | 1849 GenerateMissBranch(); |
| 1857 | 1850 |
| 1858 // Return the generated code. | 1851 // Return the generated code. |
| 1859 return GetCode(function); | 1852 return GetCode(function); |
| 1860 } | 1853 } |
| 1861 | 1854 |
| 1862 | 1855 |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2381 // Check that the receiver isn't a smi. | 2374 // Check that the receiver isn't a smi. |
| 2382 if (check != NUMBER_CHECK) { | 2375 if (check != NUMBER_CHECK) { |
| 2383 __ JumpIfSmi(r1, &miss); | 2376 __ JumpIfSmi(r1, &miss); |
| 2384 } | 2377 } |
| 2385 | 2378 |
| 2386 // Make sure that it's okay not to patch the on stack receiver | 2379 // Make sure that it's okay not to patch the on stack receiver |
| 2387 // unless we're doing a receiver map check. | 2380 // unless we're doing a receiver map check. |
| 2388 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); | 2381 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 2389 switch (check) { | 2382 switch (check) { |
| 2390 case RECEIVER_MAP_CHECK: | 2383 case RECEIVER_MAP_CHECK: |
| 2391 __ IncrementCounter(masm()->isolate()->counters()->call_const(), | 2384 __ IncrementCounter(isolate()->counters()->call_const(), 1, r0, r3); |
| 2392 1, r0, r3); | |
| 2393 | 2385 |
| 2394 // Check that the maps haven't changed. | 2386 // Check that the maps haven't changed. |
| 2395 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, | 2387 CheckPrototypes(Handle<JSObject>::cast(object), r1, holder, r0, r3, r4, |
| 2396 name, &miss); | 2388 name, &miss); |
| 2397 | 2389 |
| 2398 // Patch the receiver on the stack with the global proxy if | 2390 // Patch the receiver on the stack with the global proxy if |
| 2399 // necessary. | 2391 // necessary. |
| 2400 if (object->IsGlobalObject()) { | 2392 if (object->IsGlobalObject()) { |
| 2401 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); | 2393 __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); |
| 2402 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2394 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2572 // necessary. | 2564 // necessary. |
| 2573 if (object->IsGlobalObject()) { | 2565 if (object->IsGlobalObject()) { |
| 2574 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); | 2566 __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
| 2575 __ str(r3, MemOperand(sp, argc * kPointerSize)); | 2567 __ str(r3, MemOperand(sp, argc * kPointerSize)); |
| 2576 } | 2568 } |
| 2577 | 2569 |
| 2578 // Set up the context (function already in r1). | 2570 // Set up the context (function already in r1). |
| 2579 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 2571 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 2580 | 2572 |
| 2581 // Jump to the cached code (tail call). | 2573 // Jump to the cached code (tail call). |
| 2582 Counters* counters = masm()->isolate()->counters(); | 2574 Counters* counters = isolate()->counters(); |
| 2583 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); | 2575 __ IncrementCounter(counters->call_global_inline(), 1, r3, r4); |
| 2584 ParameterCount expected(function->shared()->formal_parameter_count()); | 2576 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 2585 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) | 2577 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) |
| 2586 ? CALL_AS_FUNCTION | 2578 ? CALL_AS_FUNCTION |
| 2587 : CALL_AS_METHOD; | 2579 : CALL_AS_METHOD; |
| 2588 // We call indirectly through the code field in the function to | 2580 // We call indirectly through the code field in the function to |
| 2589 // allow recompilation to take effect without changing any of the | 2581 // allow recompilation to take effect without changing any of the |
| 2590 // call sites. | 2582 // call sites. |
| 2591 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 2583 __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
| 2592 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, | 2584 __ InvokeCode(r3, expected, arguments(), JUMP_FUNCTION, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2615 | 2607 |
| 2616 // Stub never generated for non-global objects that require access checks. | 2608 // Stub never generated for non-global objects that require access checks. |
| 2617 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); | 2609 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); |
| 2618 | 2610 |
| 2619 __ push(receiver()); // receiver | 2611 __ push(receiver()); // receiver |
| 2620 __ mov(ip, Operand(callback)); // callback info | 2612 __ mov(ip, Operand(callback)); // callback info |
| 2621 __ Push(ip, this->name(), value()); | 2613 __ Push(ip, this->name(), value()); |
| 2622 | 2614 |
| 2623 // Do tail-call to the runtime system. | 2615 // Do tail-call to the runtime system. |
| 2624 ExternalReference store_callback_property = | 2616 ExternalReference store_callback_property = |
| 2625 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), | 2617 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
| 2626 masm()->isolate()); | |
| 2627 __ TailCallExternalReference(store_callback_property, 4, 1); | 2618 __ TailCallExternalReference(store_callback_property, 4, 1); |
| 2628 | 2619 |
| 2629 // Handle store cache miss. | 2620 // Handle store cache miss. |
| 2630 __ bind(&miss); | 2621 __ bind(&miss); |
| 2631 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2622 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2632 | 2623 |
| 2633 // Return the generated code. | 2624 // Return the generated code. |
| 2634 return GetICCode(kind(), Code::CALLBACKS, name); | 2625 return GetICCode(kind(), Code::CALLBACKS, name); |
| 2635 } | 2626 } |
| 2636 | 2627 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2699 // checks. | 2690 // checks. |
| 2700 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 2691 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
| 2701 | 2692 |
| 2702 __ Push(receiver(), this->name(), value()); | 2693 __ Push(receiver(), this->name(), value()); |
| 2703 | 2694 |
| 2704 __ mov(scratch1(), Operand(Smi::FromInt(strict_mode()))); | 2695 __ mov(scratch1(), Operand(Smi::FromInt(strict_mode()))); |
| 2705 __ push(scratch1()); // strict mode | 2696 __ push(scratch1()); // strict mode |
| 2706 | 2697 |
| 2707 // Do tail-call to the runtime system. | 2698 // Do tail-call to the runtime system. |
| 2708 ExternalReference store_ic_property = | 2699 ExternalReference store_ic_property = |
| 2709 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), | 2700 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); |
| 2710 masm()->isolate()); | |
| 2711 __ TailCallExternalReference(store_ic_property, 4, 1); | 2701 __ TailCallExternalReference(store_ic_property, 4, 1); |
| 2712 | 2702 |
| 2713 // Handle store cache miss. | 2703 // Handle store cache miss. |
| 2714 __ bind(&miss); | 2704 __ bind(&miss); |
| 2715 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2705 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2716 | 2706 |
| 2717 // Return the generated code. | 2707 // Return the generated code. |
| 2718 return GetICCode(kind(), Code::INTERCEPTOR, name); | 2708 return GetICCode(kind(), Code::INTERCEPTOR, name); |
| 2719 } | 2709 } |
| 2720 | 2710 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2739 __ ldr(scratch3(), | 2729 __ ldr(scratch3(), |
| 2740 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); | 2730 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); |
| 2741 __ cmp(scratch3(), scratch2()); | 2731 __ cmp(scratch3(), scratch2()); |
| 2742 __ b(eq, &miss); | 2732 __ b(eq, &miss); |
| 2743 | 2733 |
| 2744 // Store the value in the cell. | 2734 // Store the value in the cell. |
| 2745 __ str(value(), | 2735 __ str(value(), |
| 2746 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); | 2736 FieldMemOperand(scratch1(), JSGlobalPropertyCell::kValueOffset)); |
| 2747 // Cells are always rescanned, so no write barrier here. | 2737 // Cells are always rescanned, so no write barrier here. |
| 2748 | 2738 |
| 2749 Counters* counters = masm()->isolate()->counters(); | 2739 Counters* counters = isolate()->counters(); |
| 2750 __ IncrementCounter( | 2740 __ IncrementCounter( |
| 2751 counters->named_store_global_inline(), 1, scratch1(), scratch2()); | 2741 counters->named_store_global_inline(), 1, scratch1(), scratch2()); |
| 2752 __ Ret(); | 2742 __ Ret(); |
| 2753 | 2743 |
| 2754 // Handle store cache miss. | 2744 // Handle store cache miss. |
| 2755 __ bind(&miss); | 2745 __ bind(&miss); |
| 2756 __ IncrementCounter( | 2746 __ IncrementCounter( |
| 2757 counters->named_store_global_inline_miss(), 1, scratch1(), scratch2()); | 2747 counters->named_store_global_inline_miss(), 1, scratch1(), scratch2()); |
| 2758 TailCallBuiltin(masm(), MissBuiltin(kind())); | 2748 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 2759 | 2749 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2884 // Check for deleted property if property can actually be deleted. | 2874 // Check for deleted property if property can actually be deleted. |
| 2885 if (!is_dont_delete) { | 2875 if (!is_dont_delete) { |
| 2886 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2876 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 2887 __ cmp(r4, ip); | 2877 __ cmp(r4, ip); |
| 2888 __ b(eq, &miss); | 2878 __ b(eq, &miss); |
| 2889 } | 2879 } |
| 2890 | 2880 |
| 2891 HandlerFrontendFooter(&success, &miss); | 2881 HandlerFrontendFooter(&success, &miss); |
| 2892 __ bind(&success); | 2882 __ bind(&success); |
| 2893 | 2883 |
| 2894 Counters* counters = masm()->isolate()->counters(); | 2884 Counters* counters = isolate()->counters(); |
| 2895 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); | 2885 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); |
| 2896 __ mov(r0, r4); | 2886 __ mov(r0, r4); |
| 2897 __ Ret(); | 2887 __ Ret(); |
| 2898 | 2888 |
| 2899 // Return the generated code. | 2889 // Return the generated code. |
| 2900 return GetICCode(kind(), Code::NORMAL, name); | 2890 return GetICCode(kind(), Code::NORMAL, name); |
| 2901 } | 2891 } |
| 2902 | 2892 |
| 2903 | 2893 |
| 2904 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( | 2894 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3088 // Move argc to r1 and the JSObject to return to r0 and tag it. | 3078 // Move argc to r1 and the JSObject to return to r0 and tag it. |
| 3089 __ mov(r1, r0); | 3079 __ mov(r1, r0); |
| 3090 __ mov(r0, r4); | 3080 __ mov(r0, r4); |
| 3091 __ orr(r0, r0, Operand(kHeapObjectTag)); | 3081 __ orr(r0, r0, Operand(kHeapObjectTag)); |
| 3092 | 3082 |
| 3093 // r0: JSObject | 3083 // r0: JSObject |
| 3094 // r1: argc | 3084 // r1: argc |
| 3095 // Remove caller arguments and receiver from the stack and return. | 3085 // Remove caller arguments and receiver from the stack and return. |
| 3096 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2)); | 3086 __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2)); |
| 3097 __ add(sp, sp, Operand(kPointerSize)); | 3087 __ add(sp, sp, Operand(kPointerSize)); |
| 3098 Counters* counters = masm()->isolate()->counters(); | 3088 Counters* counters = isolate()->counters(); |
| 3099 __ IncrementCounter(counters->constructed_objects(), 1, r1, r2); | 3089 __ IncrementCounter(counters->constructed_objects(), 1, r1, r2); |
| 3100 __ IncrementCounter(counters->constructed_objects_stub(), 1, r1, r2); | 3090 __ IncrementCounter(counters->constructed_objects_stub(), 1, r1, r2); |
| 3101 __ Jump(lr); | 3091 __ Jump(lr); |
| 3102 | 3092 |
| 3103 // Jump to the generic stub in case the specialized code cannot handle the | 3093 // Jump to the generic stub in case the specialized code cannot handle the |
| 3104 // construction. | 3094 // construction. |
| 3105 __ bind(&generic_stub_call); | 3095 __ bind(&generic_stub_call); |
| 3106 Handle<Code> code = masm()->isolate()->builtins()->JSConstructStubGeneric(); | 3096 Handle<Code> code = isolate()->builtins()->JSConstructStubGeneric(); |
| 3107 __ Jump(code, RelocInfo::CODE_TARGET); | 3097 __ Jump(code, RelocInfo::CODE_TARGET); |
| 3108 | 3098 |
| 3109 // Return the generated code. | 3099 // Return the generated code. |
| 3110 return GetCode(); | 3100 return GetCode(); |
| 3111 } | 3101 } |
| 3112 | 3102 |
| 3113 | 3103 |
| 3114 #undef __ | 3104 #undef __ |
| 3115 #define __ ACCESS_MASM(masm) | 3105 #define __ ACCESS_MASM(masm) |
| 3116 | 3106 |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3667 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3657 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
| 3668 } | 3658 } |
| 3669 } | 3659 } |
| 3670 | 3660 |
| 3671 | 3661 |
| 3672 #undef __ | 3662 #undef __ |
| 3673 | 3663 |
| 3674 } } // namespace v8::internal | 3664 } } // namespace v8::internal |
| 3675 | 3665 |
| 3676 #endif // V8_TARGET_ARCH_ARM | 3666 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |