| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 8192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8203 result->set_migration_target(false); | 8203 result->set_migration_target(false); |
| 8204 | 8204 |
| 8205 #ifdef VERIFY_HEAP | 8205 #ifdef VERIFY_HEAP |
| 8206 if (FLAG_verify_heap) result->DictionaryMapVerify(); | 8206 if (FLAG_verify_heap) result->DictionaryMapVerify(); |
| 8207 #endif | 8207 #endif |
| 8208 | 8208 |
| 8209 return result; | 8209 return result; |
| 8210 } | 8210 } |
| 8211 | 8211 |
| 8212 | 8212 |
| 8213 Handle<Map> Map::CopyInitialMap(Handle<Map> map, int instance_size, |
| 8214 int in_object_properties, |
| 8215 int unused_property_fields) { |
| 8216 #ifdef DEBUG |
| 8217 Object* constructor = map->GetConstructor(); |
| 8218 DCHECK(constructor->IsJSFunction()); |
| 8219 DCHECK_EQ(*map, JSFunction::cast(constructor)->initial_map()); |
| 8220 #endif |
| 8221 Handle<Map> result = RawCopy(map, instance_size); |
| 8222 |
| 8223 // Please note instance_type and instance_size are set when allocated. |
| 8224 result->SetInObjectProperties(in_object_properties); |
| 8225 result->set_unused_property_fields(unused_property_fields); |
| 8226 |
| 8227 return result; |
| 8228 } |
| 8229 |
| 8230 |
| 8213 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) { | 8231 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) { |
| 8214 Handle<Map> result = RawCopy(map, map->instance_size()); | 8232 Handle<Map> result = RawCopy(map, map->instance_size()); |
| 8215 | 8233 |
| 8216 // Please note instance_type and instance_size are set when allocated. | 8234 // Please note instance_type and instance_size are set when allocated. |
| 8217 result->SetInObjectProperties(map->GetInObjectProperties()); | 8235 result->SetInObjectProperties(map->GetInObjectProperties()); |
| 8218 result->set_unused_property_fields(map->unused_property_fields()); | 8236 result->set_unused_property_fields(map->unused_property_fields()); |
| 8219 | 8237 |
| 8220 result->ClearCodeCache(map->GetHeap()); | 8238 result->ClearCodeCache(map->GetHeap()); |
| 8221 map->NotifyLeafMapLayoutChange(); | 8239 map->NotifyLeafMapLayoutChange(); |
| 8222 return result; | 8240 return result; |
| (...skipping 3591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11814 } | 11832 } |
| 11815 | 11833 |
| 11816 | 11834 |
| 11817 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { | 11835 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { |
| 11818 if (function->has_initial_map()) return; | 11836 if (function->has_initial_map()) return; |
| 11819 Isolate* isolate = function->GetIsolate(); | 11837 Isolate* isolate = function->GetIsolate(); |
| 11820 | 11838 |
| 11821 // First create a new map with the size and number of in-object properties | 11839 // First create a new map with the size and number of in-object properties |
| 11822 // suggested by the function. | 11840 // suggested by the function. |
| 11823 InstanceType instance_type; | 11841 InstanceType instance_type; |
| 11842 if (function->shared()->is_generator()) { |
| 11843 instance_type = JS_GENERATOR_OBJECT_TYPE; |
| 11844 } else { |
| 11845 instance_type = JS_OBJECT_TYPE; |
| 11846 } |
| 11824 int instance_size; | 11847 int instance_size; |
| 11825 int in_object_properties; | 11848 int in_object_properties; |
| 11826 if (function->shared()->is_generator()) { | 11849 function->CalculateInstanceSize(instance_type, 0, &instance_size, |
| 11827 instance_type = JS_GENERATOR_OBJECT_TYPE; | 11850 &in_object_properties); |
| 11828 instance_size = JSGeneratorObject::kSize; | 11851 |
| 11829 in_object_properties = 0; | |
| 11830 } else { | |
| 11831 instance_type = JS_OBJECT_TYPE; | |
| 11832 instance_size = function->shared()->CalculateInstanceSize(); | |
| 11833 in_object_properties = function->shared()->CalculateInObjectProperties(); | |
| 11834 } | |
| 11835 Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size); | 11852 Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size); |
| 11836 if (function->map()->is_strong()) { | 11853 if (function->map()->is_strong()) { |
| 11837 map->set_is_strong(); | 11854 map->set_is_strong(); |
| 11838 } | 11855 } |
| 11839 | 11856 |
| 11840 // Fetch or allocate prototype. | 11857 // Fetch or allocate prototype. |
| 11841 Handle<Object> prototype; | 11858 Handle<Object> prototype; |
| 11842 if (function->has_instance_prototype()) { | 11859 if (function->has_instance_prototype()) { |
| 11843 prototype = handle(function->instance_prototype(), isolate); | 11860 prototype = handle(function->instance_prototype(), isolate); |
| 11844 } else { | 11861 } else { |
| 11845 prototype = isolate->factory()->NewFunctionPrototype(function); | 11862 prototype = isolate->factory()->NewFunctionPrototype(function); |
| 11846 } | 11863 } |
| 11847 map->SetInObjectProperties(in_object_properties); | 11864 map->SetInObjectProperties(in_object_properties); |
| 11848 map->set_unused_property_fields(in_object_properties); | 11865 map->set_unused_property_fields(in_object_properties); |
| 11849 DCHECK(map->has_fast_object_elements()); | 11866 DCHECK(map->has_fast_object_elements()); |
| 11850 | 11867 |
| 11851 // Finally link initial map and constructor function. | 11868 // Finally link initial map and constructor function. |
| 11852 DCHECK(prototype->IsJSReceiver()); | 11869 DCHECK(prototype->IsJSReceiver()); |
| 11853 JSFunction::SetInitialMap(function, map, prototype); | 11870 JSFunction::SetInitialMap(function, map, prototype); |
| 11854 | 11871 |
| 11855 if (!function->shared()->is_generator()) { | 11872 if (!function->shared()->is_generator()) { |
| 11856 function->StartInobjectSlackTracking(); | 11873 function->StartInobjectSlackTracking(); |
| 11857 } | 11874 } |
| 11858 } | 11875 } |
| 11859 | 11876 |
| 11860 | 11877 |
| 11878 Handle<Map> JSFunction::EnsureDerivedHasInitialMap( |
| 11879 Handle<JSFunction> original_constructor, Handle<JSFunction> constructor) { |
| 11880 DCHECK(constructor->has_initial_map()); |
| 11881 Isolate* isolate = constructor->GetIsolate(); |
| 11882 Handle<Map> constructor_initial_map(constructor->initial_map(), isolate); |
| 11883 if (*original_constructor == *constructor) return constructor_initial_map; |
| 11884 if (original_constructor->has_initial_map()) { |
| 11885 // Check that |original_constructor|'s initial map still in sync with |
| 11886 // the |constructor|, otherwise we must create a new initial map for |
| 11887 // |original_constructor|. |
| 11888 if (original_constructor->initial_map()->GetConstructor() == *constructor) { |
| 11889 return handle(original_constructor->initial_map(), isolate); |
| 11890 } |
| 11891 } |
| 11892 |
| 11893 // First create a new map with the size and number of in-object properties |
| 11894 // suggested by the function. |
| 11895 DCHECK(!original_constructor->shared()->is_generator()); |
| 11896 DCHECK(!constructor->shared()->is_generator()); |
| 11897 |
| 11898 // Fetch or allocate prototype. |
| 11899 Handle<Object> prototype; |
| 11900 if (original_constructor->has_instance_prototype()) { |
| 11901 prototype = handle(original_constructor->instance_prototype(), isolate); |
| 11902 } else { |
| 11903 prototype = isolate->factory()->NewFunctionPrototype(original_constructor); |
| 11904 } |
| 11905 |
| 11906 // Finally link initial map and constructor function if the original |
| 11907 // constructor is actually a subclass constructor. |
| 11908 if (IsSubclassConstructor(original_constructor->shared()->kind())) { |
| 11909 InstanceType instance_type = constructor_initial_map->instance_type(); |
| 11910 int internal_fields = |
| 11911 JSObject::GetInternalFieldCount(*constructor_initial_map); |
| 11912 int instance_size; |
| 11913 int in_object_properties; |
| 11914 original_constructor->CalculateInstanceSizeForDerivedClass( |
| 11915 instance_type, internal_fields, &instance_size, &in_object_properties); |
| 11916 |
| 11917 Handle<Map> map = |
| 11918 Map::CopyInitialMap(constructor_initial_map, instance_size, |
| 11919 in_object_properties, in_object_properties); |
| 11920 |
| 11921 JSFunction::SetInitialMap(original_constructor, map, prototype); |
| 11922 map->SetConstructor(*constructor); |
| 11923 original_constructor->StartInobjectSlackTracking(); |
| 11924 return map; |
| 11925 |
| 11926 } else { |
| 11927 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); |
| 11928 DCHECK(prototype->IsJSReceiver()); |
| 11929 if (map->prototype() != *prototype) { |
| 11930 Map::SetPrototype(map, prototype, FAST_PROTOTYPE); |
| 11931 } |
| 11932 map->SetConstructor(*constructor); |
| 11933 return map; |
| 11934 } |
| 11935 } |
| 11936 |
| 11937 |
| 11861 void JSFunction::SetInstanceClassName(String* name) { | 11938 void JSFunction::SetInstanceClassName(String* name) { |
| 11862 shared()->set_instance_class_name(name); | 11939 shared()->set_instance_class_name(name); |
| 11863 } | 11940 } |
| 11864 | 11941 |
| 11865 | 11942 |
| 11866 void JSFunction::PrintName(FILE* out) { | 11943 void JSFunction::PrintName(FILE* out) { |
| 11867 base::SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); | 11944 base::SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); |
| 11868 PrintF(out, "%s", name.get()); | 11945 PrintF(out, "%s", name.get()); |
| 11869 } | 11946 } |
| 11870 | 11947 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12186 if (!script()->IsScript()) return false; | 12263 if (!script()->IsScript()) return false; |
| 12187 return !optimization_disabled(); | 12264 return !optimization_disabled(); |
| 12188 } | 12265 } |
| 12189 | 12266 |
| 12190 | 12267 |
| 12191 int SharedFunctionInfo::SourceSize() { | 12268 int SharedFunctionInfo::SourceSize() { |
| 12192 return end_position() - start_position(); | 12269 return end_position() - start_position(); |
| 12193 } | 12270 } |
| 12194 | 12271 |
| 12195 | 12272 |
| 12196 int SharedFunctionInfo::CalculateInstanceSize() { | 12273 namespace { |
| 12197 int instance_size = | 12274 |
| 12198 JSObject::kHeaderSize + | 12275 void CalculateInstanceSizeHelper(InstanceType instance_type, |
| 12199 expected_nof_properties() * kPointerSize; | 12276 int requested_internal_fields, |
| 12200 if (instance_size > JSObject::kMaxInstanceSize) { | 12277 int requested_in_object_properties, |
| 12201 instance_size = JSObject::kMaxInstanceSize; | 12278 int* instance_size, |
| 12202 } | 12279 int* in_object_properties) { |
| 12203 return instance_size; | 12280 int header_size = JSObject::GetHeaderSize(instance_type); |
| 12281 DCHECK_LE(requested_internal_fields, |
| 12282 (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2); |
| 12283 *instance_size = |
| 12284 Min(header_size + |
| 12285 ((requested_internal_fields + requested_in_object_properties) |
| 12286 << kPointerSizeLog2), |
| 12287 JSObject::kMaxInstanceSize); |
| 12288 *in_object_properties = ((*instance_size - header_size) >> kPointerSizeLog2) - |
| 12289 requested_internal_fields; |
| 12290 } |
| 12291 |
| 12292 } // namespace |
| 12293 |
| 12294 |
| 12295 void JSFunction::CalculateInstanceSize(InstanceType instance_type, |
| 12296 int requested_internal_fields, |
| 12297 int* instance_size, |
| 12298 int* in_object_properties) { |
| 12299 CalculateInstanceSizeHelper(instance_type, requested_internal_fields, |
| 12300 shared()->expected_nof_properties(), |
| 12301 instance_size, in_object_properties); |
| 12204 } | 12302 } |
| 12205 | 12303 |
| 12206 | 12304 |
| 12207 int SharedFunctionInfo::CalculateInObjectProperties() { | 12305 void JSFunction::CalculateInstanceSizeForDerivedClass( |
| 12208 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; | 12306 InstanceType instance_type, int requested_internal_fields, |
| 12307 int* instance_size, int* in_object_properties) { |
| 12308 Isolate* isolate = GetIsolate(); |
| 12309 int expected_nof_properties = 0; |
| 12310 for (PrototypeIterator iter(isolate, this, |
| 12311 PrototypeIterator::START_AT_RECEIVER); |
| 12312 !iter.IsAtEnd(); iter.Advance()) { |
| 12313 JSFunction* func = iter.GetCurrent<JSFunction>(); |
| 12314 SharedFunctionInfo* shared = func->shared(); |
| 12315 expected_nof_properties += shared->expected_nof_properties(); |
| 12316 if (!IsSubclassConstructor(shared->kind())) { |
| 12317 break; |
| 12318 } |
| 12319 } |
| 12320 CalculateInstanceSizeHelper(instance_type, requested_internal_fields, |
| 12321 expected_nof_properties, instance_size, |
| 12322 in_object_properties); |
| 12209 } | 12323 } |
| 12210 | 12324 |
| 12211 | 12325 |
| 12212 // Output the source code without any allocation in the heap. | 12326 // Output the source code without any allocation in the heap. |
| 12213 std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) { | 12327 std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) { |
| 12214 const SharedFunctionInfo* s = v.value; | 12328 const SharedFunctionInfo* s = v.value; |
| 12215 // For some native functions there is no source. | 12329 // For some native functions there is no source. |
| 12216 if (!s->HasSourceCode()) return os << "<No Source>"; | 12330 if (!s->HasSourceCode()) return os << "<No Source>"; |
| 12217 | 12331 |
| 12218 // Get the source for the script which this function came from. | 12332 // Get the source for the script which this function came from. |
| (...skipping 5679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17898 if (cell->value() != *new_value) { | 18012 if (cell->value() != *new_value) { |
| 17899 cell->set_value(*new_value); | 18013 cell->set_value(*new_value); |
| 17900 Isolate* isolate = cell->GetIsolate(); | 18014 Isolate* isolate = cell->GetIsolate(); |
| 17901 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18015 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 17902 isolate, DependentCode::kPropertyCellChangedGroup); | 18016 isolate, DependentCode::kPropertyCellChangedGroup); |
| 17903 } | 18017 } |
| 17904 } | 18018 } |
| 17905 | 18019 |
| 17906 } // namespace internal | 18020 } // namespace internal |
| 17907 } // namespace v8 | 18021 } // namespace v8 |
| OLD | NEW |