| 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 8207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8218 | 8218 |
| 8219 result->set_dictionary_map(true); | 8219 result->set_dictionary_map(true); |
| 8220 result->set_migration_target(false); | 8220 result->set_migration_target(false); |
| 8221 | 8221 |
| 8222 #ifdef VERIFY_HEAP | 8222 #ifdef VERIFY_HEAP |
| 8223 if (FLAG_verify_heap) result->DictionaryMapVerify(); | 8223 if (FLAG_verify_heap) result->DictionaryMapVerify(); |
| 8224 #endif | 8224 #endif |
| 8225 | 8225 |
| 8226 return result; | 8226 return result; |
| 8227 } | 8227 } |
| 8228 | |
| 8229 | |
| 8230 Handle<Map> Map::CopyInitialMap(Handle<Map> map, int instance_size, | |
| 8231 int in_object_properties, | |
| 8232 int unused_property_fields) { | |
| 8233 #ifdef DEBUG | |
| 8234 Object* constructor = map->GetConstructor(); | |
| 8235 DCHECK(constructor->IsJSFunction()); | |
| 8236 DCHECK_EQ(*map, JSFunction::cast(constructor)->initial_map()); | |
| 8237 #endif | |
| 8238 Handle<Map> result = RawCopy(map, instance_size); | |
| 8239 | |
| 8240 // Please note instance_type and instance_size are set when allocated. | |
| 8241 result->SetInObjectProperties(in_object_properties); | |
| 8242 result->set_unused_property_fields(unused_property_fields); | |
| 8243 | |
| 8244 return result; | |
| 8245 } | |
| 8246 | 8228 |
| 8247 | 8229 |
| 8248 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) { | 8230 Handle<Map> Map::CopyDropDescriptors(Handle<Map> map) { |
| 8249 Handle<Map> result = RawCopy(map, map->instance_size()); | 8231 Handle<Map> result = RawCopy(map, map->instance_size()); |
| 8250 | 8232 |
| 8251 // Please note instance_type and instance_size are set when allocated. | 8233 // Please note instance_type and instance_size are set when allocated. |
| 8252 result->SetInObjectProperties(map->GetInObjectProperties()); | 8234 result->SetInObjectProperties(map->GetInObjectProperties()); |
| 8253 result->set_unused_property_fields(map->unused_property_fields()); | 8235 result->set_unused_property_fields(map->unused_property_fields()); |
| 8254 | 8236 |
| 8255 result->ClearCodeCache(map->GetHeap()); | 8237 result->ClearCodeCache(map->GetHeap()); |
| (...skipping 3593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11849 } | 11831 } |
| 11850 | 11832 |
| 11851 | 11833 |
| 11852 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { | 11834 void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) { |
| 11853 if (function->has_initial_map()) return; | 11835 if (function->has_initial_map()) return; |
| 11854 Isolate* isolate = function->GetIsolate(); | 11836 Isolate* isolate = function->GetIsolate(); |
| 11855 | 11837 |
| 11856 // First create a new map with the size and number of in-object properties | 11838 // First create a new map with the size and number of in-object properties |
| 11857 // suggested by the function. | 11839 // suggested by the function. |
| 11858 InstanceType instance_type; | 11840 InstanceType instance_type; |
| 11841 int instance_size; |
| 11842 int in_object_properties; |
| 11859 if (function->shared()->is_generator()) { | 11843 if (function->shared()->is_generator()) { |
| 11860 instance_type = JS_GENERATOR_OBJECT_TYPE; | 11844 instance_type = JS_GENERATOR_OBJECT_TYPE; |
| 11845 instance_size = JSGeneratorObject::kSize; |
| 11846 in_object_properties = 0; |
| 11861 } else { | 11847 } else { |
| 11862 instance_type = JS_OBJECT_TYPE; | 11848 instance_type = JS_OBJECT_TYPE; |
| 11849 instance_size = function->shared()->CalculateInstanceSize(); |
| 11850 in_object_properties = function->shared()->CalculateInObjectProperties(); |
| 11863 } | 11851 } |
| 11864 int instance_size; | |
| 11865 int in_object_properties; | |
| 11866 function->CalculateInstanceSize(instance_type, 0, &instance_size, | |
| 11867 &in_object_properties); | |
| 11868 | |
| 11869 Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size); | 11852 Handle<Map> map = isolate->factory()->NewMap(instance_type, instance_size); |
| 11870 if (function->map()->is_strong()) { | 11853 if (function->map()->is_strong()) { |
| 11871 map->set_is_strong(); | 11854 map->set_is_strong(); |
| 11872 } | 11855 } |
| 11873 | 11856 |
| 11874 // Fetch or allocate prototype. | 11857 // Fetch or allocate prototype. |
| 11875 Handle<Object> prototype; | 11858 Handle<Object> prototype; |
| 11876 if (function->has_instance_prototype()) { | 11859 if (function->has_instance_prototype()) { |
| 11877 prototype = handle(function->instance_prototype(), isolate); | 11860 prototype = handle(function->instance_prototype(), isolate); |
| 11878 } else { | 11861 } else { |
| 11879 prototype = isolate->factory()->NewFunctionPrototype(function); | 11862 prototype = isolate->factory()->NewFunctionPrototype(function); |
| 11880 } | 11863 } |
| 11881 map->SetInObjectProperties(in_object_properties); | 11864 map->SetInObjectProperties(in_object_properties); |
| 11882 map->set_unused_property_fields(in_object_properties); | 11865 map->set_unused_property_fields(in_object_properties); |
| 11883 DCHECK(map->has_fast_object_elements()); | 11866 DCHECK(map->has_fast_object_elements()); |
| 11884 | 11867 |
| 11885 // Finally link initial map and constructor function. | 11868 // Finally link initial map and constructor function. |
| 11886 DCHECK(prototype->IsJSReceiver()); | 11869 DCHECK(prototype->IsJSReceiver()); |
| 11887 JSFunction::SetInitialMap(function, map, prototype); | 11870 JSFunction::SetInitialMap(function, map, prototype); |
| 11888 | 11871 |
| 11889 if (!function->shared()->is_generator()) { | 11872 if (!function->shared()->is_generator()) { |
| 11890 function->StartInobjectSlackTracking(); | 11873 function->StartInobjectSlackTracking(); |
| 11891 } | 11874 } |
| 11892 } | 11875 } |
| 11893 | 11876 |
| 11894 | |
| 11895 Handle<Map> JSFunction::EnsureDerivedHasInitialMap( | |
| 11896 Handle<JSFunction> original_constructor, Handle<JSFunction> constructor) { | |
| 11897 DCHECK(constructor->has_initial_map()); | |
| 11898 Isolate* isolate = constructor->GetIsolate(); | |
| 11899 Handle<Map> constructor_initial_map(constructor->initial_map(), isolate); | |
| 11900 if (*original_constructor == *constructor) return constructor_initial_map; | |
| 11901 if (original_constructor->has_initial_map()) { | |
| 11902 // Check that |original_constructor|'s initial map still in sync with | |
| 11903 // the |constructor|, otherwise we must create a new initial map for | |
| 11904 // |original_constructor|. | |
| 11905 if (original_constructor->initial_map()->GetConstructor() == *constructor) { | |
| 11906 return handle(original_constructor->initial_map(), isolate); | |
| 11907 } | |
| 11908 } | |
| 11909 | |
| 11910 // First create a new map with the size and number of in-object properties | |
| 11911 // suggested by the function. | |
| 11912 DCHECK(!original_constructor->shared()->is_generator()); | |
| 11913 DCHECK(!constructor->shared()->is_generator()); | |
| 11914 | |
| 11915 // Fetch or allocate prototype. | |
| 11916 Handle<Object> prototype; | |
| 11917 if (original_constructor->has_instance_prototype()) { | |
| 11918 prototype = handle(original_constructor->instance_prototype(), isolate); | |
| 11919 } else { | |
| 11920 prototype = isolate->factory()->NewFunctionPrototype(original_constructor); | |
| 11921 } | |
| 11922 | |
| 11923 // Finally link initial map and constructor function if the original | |
| 11924 // constructor is actually a subclass constructor. | |
| 11925 if (IsSubclassConstructor(original_constructor->shared()->kind())) { | |
| 11926 InstanceType instance_type = constructor_initial_map->instance_type(); | |
| 11927 int internal_fields = | |
| 11928 JSObject::GetInternalFieldCount(*constructor_initial_map); | |
| 11929 int instance_size; | |
| 11930 int in_object_properties; | |
| 11931 original_constructor->CalculateInstanceSizeForDerivedClass( | |
| 11932 instance_type, internal_fields, &instance_size, &in_object_properties); | |
| 11933 | |
| 11934 Handle<Map> map = | |
| 11935 Map::CopyInitialMap(constructor_initial_map, instance_size, | |
| 11936 in_object_properties, in_object_properties); | |
| 11937 | |
| 11938 JSFunction::SetInitialMap(original_constructor, map, prototype); | |
| 11939 map->SetConstructor(*constructor); | |
| 11940 original_constructor->StartInobjectSlackTracking(); | |
| 11941 return map; | |
| 11942 | |
| 11943 } else { | |
| 11944 Handle<Map> map = Map::CopyInitialMap(constructor_initial_map); | |
| 11945 DCHECK(prototype->IsJSReceiver()); | |
| 11946 if (map->prototype() != *prototype) { | |
| 11947 Map::SetPrototype(map, prototype, FAST_PROTOTYPE); | |
| 11948 } | |
| 11949 map->SetConstructor(*constructor); | |
| 11950 return map; | |
| 11951 } | |
| 11952 } | |
| 11953 | |
| 11954 | 11877 |
| 11955 void JSFunction::SetInstanceClassName(String* name) { | 11878 void JSFunction::SetInstanceClassName(String* name) { |
| 11956 shared()->set_instance_class_name(name); | 11879 shared()->set_instance_class_name(name); |
| 11957 } | 11880 } |
| 11958 | 11881 |
| 11959 | 11882 |
| 11960 void JSFunction::PrintName(FILE* out) { | 11883 void JSFunction::PrintName(FILE* out) { |
| 11961 base::SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); | 11884 base::SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); |
| 11962 PrintF(out, "%s", name.get()); | 11885 PrintF(out, "%s", name.get()); |
| 11963 } | 11886 } |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12280 if (!script()->IsScript()) return false; | 12203 if (!script()->IsScript()) return false; |
| 12281 return !optimization_disabled(); | 12204 return !optimization_disabled(); |
| 12282 } | 12205 } |
| 12283 | 12206 |
| 12284 | 12207 |
| 12285 int SharedFunctionInfo::SourceSize() { | 12208 int SharedFunctionInfo::SourceSize() { |
| 12286 return end_position() - start_position(); | 12209 return end_position() - start_position(); |
| 12287 } | 12210 } |
| 12288 | 12211 |
| 12289 | 12212 |
| 12290 namespace { | 12213 int SharedFunctionInfo::CalculateInstanceSize() { |
| 12291 | 12214 int instance_size = |
| 12292 void CalculateInstanceSizeHelper(InstanceType instance_type, | 12215 JSObject::kHeaderSize + |
| 12293 int requested_internal_fields, | 12216 expected_nof_properties() * kPointerSize; |
| 12294 int requested_in_object_properties, | 12217 if (instance_size > JSObject::kMaxInstanceSize) { |
| 12295 int* instance_size, | 12218 instance_size = JSObject::kMaxInstanceSize; |
| 12296 int* in_object_properties) { | 12219 } |
| 12297 int header_size = JSObject::GetHeaderSize(instance_type); | 12220 return instance_size; |
| 12298 DCHECK_LE(requested_internal_fields, | |
| 12299 (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2); | |
| 12300 *instance_size = | |
| 12301 Min(header_size + | |
| 12302 ((requested_internal_fields + requested_in_object_properties) | |
| 12303 << kPointerSizeLog2), | |
| 12304 JSObject::kMaxInstanceSize); | |
| 12305 *in_object_properties = ((*instance_size - header_size) >> kPointerSizeLog2) - | |
| 12306 requested_internal_fields; | |
| 12307 } | |
| 12308 | |
| 12309 } // namespace | |
| 12310 | |
| 12311 | |
| 12312 void JSFunction::CalculateInstanceSize(InstanceType instance_type, | |
| 12313 int requested_internal_fields, | |
| 12314 int* instance_size, | |
| 12315 int* in_object_properties) { | |
| 12316 CalculateInstanceSizeHelper(instance_type, requested_internal_fields, | |
| 12317 shared()->expected_nof_properties(), | |
| 12318 instance_size, in_object_properties); | |
| 12319 } | 12221 } |
| 12320 | 12222 |
| 12321 | 12223 |
| 12322 void JSFunction::CalculateInstanceSizeForDerivedClass( | 12224 int SharedFunctionInfo::CalculateInObjectProperties() { |
| 12323 InstanceType instance_type, int requested_internal_fields, | 12225 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; |
| 12324 int* instance_size, int* in_object_properties) { | |
| 12325 Isolate* isolate = GetIsolate(); | |
| 12326 int expected_nof_properties = 0; | |
| 12327 for (PrototypeIterator iter(isolate, this, | |
| 12328 PrototypeIterator::START_AT_RECEIVER); | |
| 12329 !iter.IsAtEnd(); iter.Advance()) { | |
| 12330 JSFunction* func = iter.GetCurrent<JSFunction>(); | |
| 12331 SharedFunctionInfo* shared = func->shared(); | |
| 12332 expected_nof_properties += shared->expected_nof_properties(); | |
| 12333 if (!IsSubclassConstructor(shared->kind())) { | |
| 12334 break; | |
| 12335 } | |
| 12336 } | |
| 12337 CalculateInstanceSizeHelper(instance_type, requested_internal_fields, | |
| 12338 expected_nof_properties, instance_size, | |
| 12339 in_object_properties); | |
| 12340 } | 12226 } |
| 12341 | 12227 |
| 12342 | 12228 |
| 12343 // Output the source code without any allocation in the heap. | 12229 // Output the source code without any allocation in the heap. |
| 12344 std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) { | 12230 std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) { |
| 12345 const SharedFunctionInfo* s = v.value; | 12231 const SharedFunctionInfo* s = v.value; |
| 12346 // For some native functions there is no source. | 12232 // For some native functions there is no source. |
| 12347 if (!s->HasSourceCode()) return os << "<No Source>"; | 12233 if (!s->HasSourceCode()) return os << "<No Source>"; |
| 12348 | 12234 |
| 12349 // Get the source for the script which this function came from. | 12235 // Get the source for the script which this function came from. |
| (...skipping 5679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18029 if (cell->value() != *new_value) { | 17915 if (cell->value() != *new_value) { |
| 18030 cell->set_value(*new_value); | 17916 cell->set_value(*new_value); |
| 18031 Isolate* isolate = cell->GetIsolate(); | 17917 Isolate* isolate = cell->GetIsolate(); |
| 18032 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17918 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18033 isolate, DependentCode::kPropertyCellChangedGroup); | 17919 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18034 } | 17920 } |
| 18035 } | 17921 } |
| 18036 | 17922 |
| 18037 } // namespace internal | 17923 } // namespace internal |
| 18038 } // namespace v8 | 17924 } // namespace v8 |
| OLD | NEW |