Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: src/x87/code-stubs-x87.cc

Issue 1991663002: X87: [es6] Reintroduce the instanceof operator in the backends. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/x87/builtins-x87.cc ('k') | src/x87/interface-descriptors-x87.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/api-arguments.h" 8 #include "src/api-arguments.h"
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 1752 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 __ pop(esi); 1763 __ pop(esi);
1764 __ pop(edi); 1764 __ pop(edi);
1765 __ add(esp, Immediate(2 * kPointerSize)); // remove markers 1765 __ add(esp, Immediate(2 * kPointerSize)); // remove markers
1766 1766
1767 // Restore frame pointer and return. 1767 // Restore frame pointer and return.
1768 __ pop(ebp); 1768 __ pop(ebp);
1769 __ ret(0); 1769 __ ret(0);
1770 } 1770 }
1771 1771
1772 1772
1773 void InstanceOfStub::Generate(MacroAssembler* masm) {
1774 Register const object = edx; // Object (lhs).
1775 Register const function = eax; // Function (rhs).
1776 Register const object_map = ecx; // Map of {object}.
1777 Register const function_map = ebx; // Map of {function}.
1778 Register const function_prototype = function_map; // Prototype of {function}.
1779 Register const scratch = edi;
1780
1781 DCHECK(object.is(InstanceOfDescriptor::LeftRegister()));
1782 DCHECK(function.is(InstanceOfDescriptor::RightRegister()));
1783
1784 // Check if {object} is a smi.
1785 Label object_is_smi;
1786 __ JumpIfSmi(object, &object_is_smi, Label::kNear);
1787
1788 // Lookup the {function} and the {object} map in the global instanceof cache.
1789 // Note: This is safe because we clear the global instanceof cache whenever
1790 // we change the prototype of any object.
1791 Label fast_case, slow_case;
1792 __ mov(object_map, FieldOperand(object, HeapObject::kMapOffset));
1793 __ CompareRoot(function, scratch, Heap::kInstanceofCacheFunctionRootIndex);
1794 __ j(not_equal, &fast_case, Label::kNear);
1795 __ CompareRoot(object_map, scratch, Heap::kInstanceofCacheMapRootIndex);
1796 __ j(not_equal, &fast_case, Label::kNear);
1797 __ LoadRoot(eax, Heap::kInstanceofCacheAnswerRootIndex);
1798 __ ret(0);
1799
1800 // If {object} is a smi we can safely return false if {function} is a JS
1801 // function, otherwise we have to miss to the runtime and throw an exception.
1802 __ bind(&object_is_smi);
1803 __ JumpIfSmi(function, &slow_case);
1804 __ CmpObjectType(function, JS_FUNCTION_TYPE, function_map);
1805 __ j(not_equal, &slow_case);
1806 __ LoadRoot(eax, Heap::kFalseValueRootIndex);
1807 __ ret(0);
1808
1809 // Fast-case: The {function} must be a valid JSFunction.
1810 __ bind(&fast_case);
1811 __ JumpIfSmi(function, &slow_case);
1812 __ CmpObjectType(function, JS_FUNCTION_TYPE, function_map);
1813 __ j(not_equal, &slow_case);
1814
1815 // Go to the runtime if the function is not a constructor.
1816 __ test_b(FieldOperand(function_map, Map::kBitFieldOffset),
1817 Immediate(1 << Map::kIsConstructor));
1818 __ j(zero, &slow_case);
1819
1820 // Ensure that {function} has an instance prototype.
1821 __ test_b(FieldOperand(function_map, Map::kBitFieldOffset),
1822 Immediate(1 << Map::kHasNonInstancePrototype));
1823 __ j(not_zero, &slow_case);
1824
1825 // Get the "prototype" (or initial map) of the {function}.
1826 __ mov(function_prototype,
1827 FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
1828 __ AssertNotSmi(function_prototype);
1829
1830 // Resolve the prototype if the {function} has an initial map. Afterwards the
1831 // {function_prototype} will be either the JSReceiver prototype object or the
1832 // hole value, which means that no instances of the {function} were created so
1833 // far and hence we should return false.
1834 Label function_prototype_valid;
1835 Register const function_prototype_map = scratch;
1836 __ CmpObjectType(function_prototype, MAP_TYPE, function_prototype_map);
1837 __ j(not_equal, &function_prototype_valid, Label::kNear);
1838 __ mov(function_prototype,
1839 FieldOperand(function_prototype, Map::kPrototypeOffset));
1840 __ bind(&function_prototype_valid);
1841 __ AssertNotSmi(function_prototype);
1842
1843 // Update the global instanceof cache with the current {object} map and
1844 // {function}. The cached answer will be set when it is known below.
1845 __ StoreRoot(function, scratch, Heap::kInstanceofCacheFunctionRootIndex);
1846 __ StoreRoot(object_map, scratch, Heap::kInstanceofCacheMapRootIndex);
1847
1848 // Loop through the prototype chain looking for the {function} prototype.
1849 // Assume true, and change to false if not found.
1850 Label done, loop, fast_runtime_fallback;
1851 __ mov(eax, isolate()->factory()->true_value());
1852 __ bind(&loop);
1853
1854 // Check if the object needs to be access checked.
1855 __ test_b(FieldOperand(object_map, Map::kBitFieldOffset),
1856 Immediate(1 << Map::kIsAccessCheckNeeded));
1857 __ j(not_zero, &fast_runtime_fallback, Label::kNear);
1858 // Check if the current object is a Proxy.
1859 __ CmpInstanceType(object_map, JS_PROXY_TYPE);
1860 __ j(equal, &fast_runtime_fallback, Label::kNear);
1861
1862 __ mov(object, FieldOperand(object_map, Map::kPrototypeOffset));
1863 __ cmp(object, function_prototype);
1864 __ j(equal, &done, Label::kNear);
1865 __ mov(object_map, FieldOperand(object, HeapObject::kMapOffset));
1866 __ cmp(object, isolate()->factory()->null_value());
1867 __ j(not_equal, &loop);
1868 __ mov(eax, isolate()->factory()->false_value());
1869
1870 __ bind(&done);
1871 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheAnswerRootIndex);
1872 __ ret(0);
1873
1874 // Found Proxy or access check needed: Call the runtime.
1875 __ bind(&fast_runtime_fallback);
1876 __ PopReturnAddressTo(scratch);
1877 __ Push(object);
1878 __ Push(function_prototype);
1879 __ PushReturnAddressFrom(scratch);
1880 // Invalidate the instanceof cache.
1881 __ Move(eax, Immediate(Smi::FromInt(0)));
1882 __ StoreRoot(eax, scratch, Heap::kInstanceofCacheFunctionRootIndex);
1883 __ TailCallRuntime(Runtime::kHasInPrototypeChain);
1884
1885 // Slow-case: Call the %InstanceOf runtime function.
1886 __ bind(&slow_case);
1887 __ PopReturnAddressTo(scratch);
1888 __ Push(object);
1889 __ Push(function);
1890 __ PushReturnAddressFrom(scratch);
1891 __ TailCallRuntime(is_es6_instanceof() ? Runtime::kOrdinaryHasInstance
1892 : Runtime::kInstanceOf);
1893 }
1894
1895
1896 // ------------------------------------------------------------------------- 1773 // -------------------------------------------------------------------------
1897 // StringCharCodeAtGenerator 1774 // StringCharCodeAtGenerator
1898 1775
1899 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 1776 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
1900 // If the receiver is a smi trigger the non-string case. 1777 // If the receiver is a smi trigger the non-string case.
1901 if (check_mode_ == RECEIVER_IS_UNKNOWN) { 1778 if (check_mode_ == RECEIVER_IS_UNKNOWN) {
1902 __ JumpIfSmi(object_, receiver_not_string_); 1779 __ JumpIfSmi(object_, receiver_not_string_);
1903 1780
1904 // Fetch the instance type of the receiver into result register. 1781 // Fetch the instance type of the receiver into result register.
1905 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); 1782 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
(...skipping 3607 matching lines...) Expand 10 before | Expand all | Expand 10 after
5513 kStackUnwindSpace, nullptr, return_value_operand, 5390 kStackUnwindSpace, nullptr, return_value_operand,
5514 NULL); 5391 NULL);
5515 } 5392 }
5516 5393
5517 #undef __ 5394 #undef __
5518 5395
5519 } // namespace internal 5396 } // namespace internal
5520 } // namespace v8 5397 } // namespace v8
5521 5398
5522 #endif // V8_TARGET_ARCH_X87 5399 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « src/x87/builtins-x87.cc ('k') | src/x87/interface-descriptors-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698