Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #include "src/factory.h" | 5 #include "src/factory.h" |
| 6 | 6 |
| 7 #include "src/allocation-site-scopes.h" | 7 #include "src/allocation-site-scopes.h" |
| 8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
| 9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
| 10 #include "src/macro-assembler.h" | 10 #include "src/macro-assembler.h" |
| (...skipping 1759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1770 Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE); | 1770 Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE); |
| 1771 result->InitializeBody(map->instance_size(), Smi::FromInt(0)); | 1771 result->InitializeBody(map->instance_size(), Smi::FromInt(0)); |
| 1772 result->set_handler(*handler); | 1772 result->set_handler(*handler); |
| 1773 result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER); | 1773 result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER); |
| 1774 result->set_call_trap(*call_trap); | 1774 result->set_call_trap(*call_trap); |
| 1775 result->set_construct_trap(*construct_trap); | 1775 result->set_construct_trap(*construct_trap); |
| 1776 return result; | 1776 return result; |
| 1777 } | 1777 } |
| 1778 | 1778 |
| 1779 | 1779 |
| 1780 void Factory::ReinitializeJSReceiver(Handle<JSReceiver> object, | 1780 void Factory::ReinitializeJSProxy(Handle<JSProxy> proxy, InstanceType type, |
| 1781 InstanceType type, | 1781 int size) { |
| 1782 int size) { | 1782 DCHECK(type == JS_OBJECT_TYPE || type == JS_FUNCTION_TYPE); |
| 1783 DCHECK(type >= FIRST_JS_OBJECT_TYPE); | |
| 1784 | 1783 |
| 1785 // Allocate fresh map. | 1784 // Allocate fresh map. |
| 1786 // TODO(rossberg): Once we optimize proxies, cache these maps. | 1785 // TODO(rossberg): Once we optimize proxies, cache these maps. |
| 1787 Handle<Map> map = NewMap(type, size); | 1786 Handle<Map> map = NewMap(type, size); |
| 1788 | 1787 |
| 1789 // Check that the receiver has at least the size of the fresh object. | 1788 // Check that the receiver has at least the size of the fresh object. |
| 1790 int size_difference = object->map()->instance_size() - map->instance_size(); | 1789 int size_difference = proxy->map()->instance_size() - map->instance_size(); |
| 1791 DCHECK(size_difference >= 0); | 1790 DCHECK(size_difference >= 0); |
| 1792 | 1791 |
| 1793 map->set_prototype(object->map()->prototype()); | 1792 map->set_prototype(proxy->map()->prototype()); |
| 1794 | 1793 |
| 1795 // Allocate the backing storage for the properties. | 1794 // Allocate the backing storage for the properties. |
| 1796 int prop_size = map->InitialPropertiesLength(); | 1795 int prop_size = map->InitialPropertiesLength(); |
| 1797 Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED); | 1796 Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED); |
| 1798 | 1797 |
| 1799 Heap* heap = isolate()->heap(); | 1798 Heap* heap = isolate()->heap(); |
| 1800 MaybeHandle<SharedFunctionInfo> shared; | 1799 MaybeHandle<SharedFunctionInfo> shared; |
| 1801 if (type == JS_FUNCTION_TYPE) { | 1800 if (type == JS_FUNCTION_TYPE) { |
| 1802 OneByteStringKey key(STATIC_ASCII_VECTOR("<freezing call trap>"), | 1801 OneByteStringKey key(STATIC_ASCII_VECTOR("<freezing call trap>"), |
| 1803 heap->HashSeed()); | 1802 heap->HashSeed()); |
| 1804 Handle<String> name = InternalizeStringWithKey(&key); | 1803 Handle<String> name = InternalizeStringWithKey(&key); |
| 1805 shared = NewSharedFunctionInfo(name, MaybeHandle<Code>()); | 1804 shared = NewSharedFunctionInfo(name, MaybeHandle<Code>()); |
| 1806 } | 1805 } |
| 1807 | 1806 |
| 1808 // In order to keep heap in consistent state there must be no allocations | 1807 // In order to keep heap in consistent state there must be no allocations |
| 1809 // before object re-initialization is finished and filler object is installed. | 1808 // before object re-initialization is finished and filler object is installed. |
| 1810 DisallowHeapAllocation no_allocation; | 1809 DisallowHeapAllocation no_allocation; |
| 1811 | 1810 |
| 1812 // Put in filler if the new object is smaller than the old. | 1811 // Put in filler if the new object is smaller than the old. |
| 1813 if (size_difference > 0) { | 1812 if (size_difference > 0) { |
| 1814 Address address = object->address(); | 1813 Address address = proxy->address(); |
| 1815 heap->CreateFillerObjectAt(address + map->instance_size(), size_difference); | 1814 heap->CreateFillerObjectAt(address + map->instance_size(), size_difference); |
| 1816 heap->AdjustLiveBytes(address, -size_difference, Heap::FROM_MUTATOR); | 1815 heap->AdjustLiveBytes(address, -size_difference, Heap::FROM_MUTATOR); |
| 1817 } | 1816 } |
| 1818 | 1817 |
| 1819 // Reset the map for the object. | 1818 // Reset the map for the object. |
| 1820 object->synchronized_set_map(*map); | 1819 proxy->synchronized_set_map(*map); |
| 1821 Handle<JSObject> jsobj = Handle<JSObject>::cast(object); | 1820 Handle<JSObject> jsobj = Handle<JSObject>::cast(proxy); |
| 1822 | 1821 |
| 1823 // Reinitialize the object from the constructor map. | 1822 // Reinitialize the object from the constructor map. |
| 1824 heap->InitializeJSObjectFromMap(*jsobj, *properties, *map); | 1823 heap->InitializeJSObjectFromMap(*jsobj, *properties, *map); |
| 1825 | 1824 |
| 1825 // The current native context is used to set up certain bits. | |
| 1826 // TODO(adamk): Using the current context seems wrong, it should be whatever | |
| 1827 // context the JSProxy originated in. But that context isn't stored anywhere. | |
|
Toon Verwaest
2014/08/27 09:54:34
And I think shouldn't be stored anywhere...
| |
| 1828 Handle<Context> context(isolate()->native_context()); | |
| 1829 | |
| 1826 // Functions require some minimal initialization. | 1830 // Functions require some minimal initialization. |
| 1827 if (type == JS_FUNCTION_TYPE) { | 1831 if (type == JS_FUNCTION_TYPE) { |
| 1828 map->set_function_with_prototype(true); | 1832 map->set_function_with_prototype(true); |
| 1829 Handle<JSFunction> js_function = Handle<JSFunction>::cast(object); | 1833 Handle<JSFunction> js_function = Handle<JSFunction>::cast(proxy); |
| 1830 Handle<Context> context(isolate()->native_context()); | |
| 1831 InitializeFunction(js_function, shared.ToHandleChecked(), context); | 1834 InitializeFunction(js_function, shared.ToHandleChecked(), context); |
| 1835 } else { | |
| 1836 // Provide JSObjects with a constructor. | |
| 1837 map->set_constructor(context->object_function()); | |
| 1832 } | 1838 } |
| 1833 } | 1839 } |
| 1834 | 1840 |
| 1835 | 1841 |
| 1836 void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object, | 1842 void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object, |
| 1837 Handle<JSFunction> constructor) { | 1843 Handle<JSFunction> constructor) { |
| 1838 DCHECK(constructor->has_initial_map()); | 1844 DCHECK(constructor->has_initial_map()); |
| 1839 Handle<Map> map(constructor->initial_map(), isolate()); | 1845 Handle<Map> map(constructor->initial_map(), isolate()); |
| 1840 | 1846 |
| 1841 // The proxy's hash should be retained across reinitialization. | 1847 // The proxy's hash should be retained across reinitialization. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1859 | 1865 |
| 1860 Heap* heap = isolate()->heap(); | 1866 Heap* heap = isolate()->heap(); |
| 1861 // Reinitialize the object from the constructor map. | 1867 // Reinitialize the object from the constructor map. |
| 1862 heap->InitializeJSObjectFromMap(*object, *properties, *map); | 1868 heap->InitializeJSObjectFromMap(*object, *properties, *map); |
| 1863 | 1869 |
| 1864 // Restore the saved hash. | 1870 // Restore the saved hash. |
| 1865 object->set_hash(*hash); | 1871 object->set_hash(*hash); |
| 1866 } | 1872 } |
| 1867 | 1873 |
| 1868 | 1874 |
| 1869 void Factory::BecomeJSObject(Handle<JSReceiver> object) { | 1875 void Factory::BecomeJSObject(Handle<JSProxy> proxy) { |
| 1870 ReinitializeJSReceiver(object, JS_OBJECT_TYPE, JSObject::kHeaderSize); | 1876 ReinitializeJSProxy(proxy, JS_OBJECT_TYPE, JSObject::kHeaderSize); |
| 1871 } | 1877 } |
| 1872 | 1878 |
| 1873 | 1879 |
| 1874 void Factory::BecomeJSFunction(Handle<JSReceiver> object) { | 1880 void Factory::BecomeJSFunction(Handle<JSProxy> proxy) { |
| 1875 ReinitializeJSReceiver(object, JS_FUNCTION_TYPE, JSFunction::kSize); | 1881 ReinitializeJSProxy(proxy, JS_FUNCTION_TYPE, JSFunction::kSize); |
| 1876 } | 1882 } |
| 1877 | 1883 |
| 1878 | 1884 |
| 1879 Handle<FixedArray> Factory::NewTypeFeedbackVector(int slot_count) { | 1885 Handle<FixedArray> Factory::NewTypeFeedbackVector(int slot_count) { |
| 1880 // Ensure we can skip the write barrier | 1886 // Ensure we can skip the write barrier |
| 1881 DCHECK_EQ(isolate()->heap()->uninitialized_symbol(), | 1887 DCHECK_EQ(isolate()->heap()->uninitialized_symbol(), |
| 1882 *TypeFeedbackInfo::UninitializedSentinel(isolate())); | 1888 *TypeFeedbackInfo::UninitializedSentinel(isolate())); |
| 1883 | 1889 |
| 1884 CALL_HEAP_FUNCTION( | 1890 CALL_HEAP_FUNCTION( |
| 1885 isolate(), | 1891 isolate(), |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2379 return Handle<Object>::null(); | 2385 return Handle<Object>::null(); |
| 2380 } | 2386 } |
| 2381 | 2387 |
| 2382 | 2388 |
| 2383 Handle<Object> Factory::ToBoolean(bool value) { | 2389 Handle<Object> Factory::ToBoolean(bool value) { |
| 2384 return value ? true_value() : false_value(); | 2390 return value ? true_value() : false_value(); |
| 2385 } | 2391 } |
| 2386 | 2392 |
| 2387 | 2393 |
| 2388 } } // namespace v8::internal | 2394 } } // namespace v8::internal |
| OLD | NEW |