| 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 2854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2865 } | 2865 } |
| 2866 set_polymorphic_code_cache(PolymorphicCodeCache::cast(obj)); | 2866 set_polymorphic_code_cache(PolymorphicCodeCache::cast(obj)); |
| 2867 | 2867 |
| 2868 set_instanceof_cache_function(Smi::FromInt(0)); | 2868 set_instanceof_cache_function(Smi::FromInt(0)); |
| 2869 set_instanceof_cache_map(Smi::FromInt(0)); | 2869 set_instanceof_cache_map(Smi::FromInt(0)); |
| 2870 set_instanceof_cache_answer(Smi::FromInt(0)); | 2870 set_instanceof_cache_answer(Smi::FromInt(0)); |
| 2871 | 2871 |
| 2872 CreateFixedStubs(); | 2872 CreateFixedStubs(); |
| 2873 | 2873 |
| 2874 // Allocate the dictionary of intrinsic function names. | 2874 // Allocate the dictionary of intrinsic function names. |
| 2875 { MaybeObject* maybe_obj = StringDictionary::Allocate(Runtime::kNumFunctions); | 2875 { MaybeObject* maybe_obj = NameDictionary::Allocate(Runtime::kNumFunctions); |
| 2876 if (!maybe_obj->ToObject(&obj)) return false; | 2876 if (!maybe_obj->ToObject(&obj)) return false; |
| 2877 } | 2877 } |
| 2878 { MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(this, | 2878 { MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(this, |
| 2879 obj); | 2879 obj); |
| 2880 if (!maybe_obj->ToObject(&obj)) return false; | 2880 if (!maybe_obj->ToObject(&obj)) return false; |
| 2881 } | 2881 } |
| 2882 set_intrinsic_function_names(StringDictionary::cast(obj)); | 2882 set_intrinsic_function_names(NameDictionary::cast(obj)); |
| 2883 | 2883 |
| 2884 { MaybeObject* maybe_obj = AllocateInitialNumberStringCache(); | 2884 { MaybeObject* maybe_obj = AllocateInitialNumberStringCache(); |
| 2885 if (!maybe_obj->ToObject(&obj)) return false; | 2885 if (!maybe_obj->ToObject(&obj)) return false; |
| 2886 } | 2886 } |
| 2887 set_number_string_cache(FixedArray::cast(obj)); | 2887 set_number_string_cache(FixedArray::cast(obj)); |
| 2888 | 2888 |
| 2889 // Allocate cache for single character one byte strings. | 2889 // Allocate cache for single character one byte strings. |
| 2890 { MaybeObject* maybe_obj = | 2890 { MaybeObject* maybe_obj = |
| 2891 AllocateFixedArray(String::kMaxOneByteCharCode + 1, TENURED); | 2891 AllocateFixedArray(String::kMaxOneByteCharCode + 1, TENURED); |
| 2892 if (!maybe_obj->ToObject(&obj)) return false; | 2892 if (!maybe_obj->ToObject(&obj)) return false; |
| (...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4043 ASSERT(JSObject::cast(result)->HasFastProperties()); | 4043 ASSERT(JSObject::cast(result)->HasFastProperties()); |
| 4044 ASSERT(JSObject::cast(result)->HasFastObjectElements()); | 4044 ASSERT(JSObject::cast(result)->HasFastObjectElements()); |
| 4045 | 4045 |
| 4046 return result; | 4046 return result; |
| 4047 } | 4047 } |
| 4048 | 4048 |
| 4049 | 4049 |
| 4050 static bool HasDuplicates(DescriptorArray* descriptors) { | 4050 static bool HasDuplicates(DescriptorArray* descriptors) { |
| 4051 int count = descriptors->number_of_descriptors(); | 4051 int count = descriptors->number_of_descriptors(); |
| 4052 if (count > 1) { | 4052 if (count > 1) { |
| 4053 String* prev_key = descriptors->GetKey(0); | 4053 Name* prev_key = descriptors->GetKey(0); |
| 4054 for (int i = 1; i != count; i++) { | 4054 for (int i = 1; i != count; i++) { |
| 4055 String* current_key = descriptors->GetKey(i); | 4055 Name* current_key = descriptors->GetKey(i); |
| 4056 if (prev_key == current_key) return true; | 4056 if (prev_key == current_key) return true; |
| 4057 prev_key = current_key; | 4057 prev_key = current_key; |
| 4058 } | 4058 } |
| 4059 } | 4059 } |
| 4060 return false; | 4060 return false; |
| 4061 } | 4061 } |
| 4062 | 4062 |
| 4063 | 4063 |
| 4064 MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) { | 4064 MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) { |
| 4065 ASSERT(!fun->has_initial_map()); | 4065 ASSERT(!fun->has_initial_map()); |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4358 // global objects. They will be unused once we normalize the object. | 4358 // global objects. They will be unused once we normalize the object. |
| 4359 ASSERT(map->unused_property_fields() == 0); | 4359 ASSERT(map->unused_property_fields() == 0); |
| 4360 ASSERT(map->inobject_properties() == 0); | 4360 ASSERT(map->inobject_properties() == 0); |
| 4361 | 4361 |
| 4362 // Initial size of the backing store to avoid resize of the storage during | 4362 // Initial size of the backing store to avoid resize of the storage during |
| 4363 // bootstrapping. The size differs between the JS global object ad the | 4363 // bootstrapping. The size differs between the JS global object ad the |
| 4364 // builtins object. | 4364 // builtins object. |
| 4365 int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512; | 4365 int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512; |
| 4366 | 4366 |
| 4367 // Allocate a dictionary object for backing storage. | 4367 // Allocate a dictionary object for backing storage. |
| 4368 StringDictionary* dictionary; | 4368 NameDictionary* dictionary; |
| 4369 MaybeObject* maybe_dictionary = | 4369 MaybeObject* maybe_dictionary = |
| 4370 StringDictionary::Allocate( | 4370 NameDictionary::Allocate( |
| 4371 map->NumberOfOwnDescriptors() * 2 + initial_size); | 4371 map->NumberOfOwnDescriptors() * 2 + initial_size); |
| 4372 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; | 4372 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; |
| 4373 | 4373 |
| 4374 // The global object might be created from an object template with accessors. | 4374 // The global object might be created from an object template with accessors. |
| 4375 // Fill these accessors into the dictionary. | 4375 // Fill these accessors into the dictionary. |
| 4376 DescriptorArray* descs = map->instance_descriptors(); | 4376 DescriptorArray* descs = map->instance_descriptors(); |
| 4377 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 4377 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 4378 PropertyDetails details = descs->GetDetails(i); | 4378 PropertyDetails details = descs->GetDetails(i); |
| 4379 ASSERT(details.type() == CALLBACKS); // Only accessors are expected. | 4379 ASSERT(details.type() == CALLBACKS); // Only accessors are expected. |
| 4380 PropertyDetails d = PropertyDetails(details.attributes(), | 4380 PropertyDetails d = PropertyDetails(details.attributes(), |
| (...skipping 2803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7184 switch (collector_) { | 7184 switch (collector_) { |
| 7185 case SCAVENGER: | 7185 case SCAVENGER: |
| 7186 return "Scavenge"; | 7186 return "Scavenge"; |
| 7187 case MARK_COMPACTOR: | 7187 case MARK_COMPACTOR: |
| 7188 return "Mark-sweep"; | 7188 return "Mark-sweep"; |
| 7189 } | 7189 } |
| 7190 return "Unknown GC"; | 7190 return "Unknown GC"; |
| 7191 } | 7191 } |
| 7192 | 7192 |
| 7193 | 7193 |
| 7194 int KeyedLookupCache::Hash(Map* map, String* name) { | 7194 int KeyedLookupCache::Hash(Map* map, Name* name) { |
| 7195 // Uses only lower 32 bits if pointers are larger. | 7195 // Uses only lower 32 bits if pointers are larger. |
| 7196 uintptr_t addr_hash = | 7196 uintptr_t addr_hash = |
| 7197 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)) >> kMapHashShift; | 7197 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)) >> kMapHashShift; |
| 7198 return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask); | 7198 return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask); |
| 7199 } | 7199 } |
| 7200 | 7200 |
| 7201 | 7201 |
| 7202 int KeyedLookupCache::Lookup(Map* map, String* name) { | 7202 int KeyedLookupCache::Lookup(Map* map, Name* name) { |
| 7203 int index = (Hash(map, name) & kHashMask); | 7203 int index = (Hash(map, name) & kHashMask); |
| 7204 for (int i = 0; i < kEntriesPerBucket; i++) { | 7204 for (int i = 0; i < kEntriesPerBucket; i++) { |
| 7205 Key& key = keys_[index + i]; | 7205 Key& key = keys_[index + i]; |
| 7206 if ((key.map == map) && key.name->Equals(name)) { | 7206 if ((key.map == map) && key.name->Equals(name)) { |
| 7207 return field_offsets_[index + i]; | 7207 return field_offsets_[index + i]; |
| 7208 } | 7208 } |
| 7209 } | 7209 } |
| 7210 return kNotFound; | 7210 return kNotFound; |
| 7211 } | 7211 } |
| 7212 | 7212 |
| 7213 | 7213 |
| 7214 void KeyedLookupCache::Update(Map* map, String* name, int field_offset) { | 7214 void KeyedLookupCache::Update(Map* map, Name* name, int field_offset) { |
| 7215 String* internalized_name; | 7215 if (!name->IsUniqueName()) { |
| 7216 if (HEAP->InternalizeStringIfExists(name, &internalized_name)) { | 7216 String* internalized_string; |
| 7217 int index = (Hash(map, internalized_name) & kHashMask); | 7217 if (!HEAP->InternalizeStringIfExists( |
| 7218 // After a GC there will be free slots, so we use them in order (this may | 7218 String::cast(name), &internalized_string)) { |
| 7219 // help to get the most frequently used one in position 0). | 7219 return; |
| 7220 for (int i = 0; i< kEntriesPerBucket; i++) { | |
| 7221 Key& key = keys_[index]; | |
| 7222 Object* free_entry_indicator = NULL; | |
| 7223 if (key.map == free_entry_indicator) { | |
| 7224 key.map = map; | |
| 7225 key.name = internalized_name; | |
| 7226 field_offsets_[index + i] = field_offset; | |
| 7227 return; | |
| 7228 } | |
| 7229 } | 7220 } |
| 7230 // No free entry found in this bucket, so we move them all down one and | 7221 name = internalized_string; |
| 7231 // put the new entry at position zero. | 7222 } |
| 7232 for (int i = kEntriesPerBucket - 1; i > 0; i--) { | 7223 |
| 7233 Key& key = keys_[index + i]; | 7224 int index = (Hash(map, name) & kHashMask); |
| 7234 Key& key2 = keys_[index + i - 1]; | 7225 // After a GC there will be free slots, so we use them in order (this may |
| 7235 key = key2; | 7226 // help to get the most frequently used one in position 0). |
| 7236 field_offsets_[index + i] = field_offsets_[index + i - 1]; | 7227 for (int i = 0; i< kEntriesPerBucket; i++) { |
| 7228 Key& key = keys_[index]; |
| 7229 Object* free_entry_indicator = NULL; |
| 7230 if (key.map == free_entry_indicator) { |
| 7231 key.map = map; |
| 7232 key.name = name; |
| 7233 field_offsets_[index + i] = field_offset; |
| 7234 return; |
| 7237 } | 7235 } |
| 7236 } |
| 7237 // No free entry found in this bucket, so we move them all down one and |
| 7238 // put the new entry at position zero. |
| 7239 for (int i = kEntriesPerBucket - 1; i > 0; i--) { |
| 7240 Key& key = keys_[index + i]; |
| 7241 Key& key2 = keys_[index + i - 1]; |
| 7242 key = key2; |
| 7243 field_offsets_[index + i] = field_offsets_[index + i - 1]; |
| 7244 } |
| 7238 | 7245 |
| 7239 // Write the new first entry. | 7246 // Write the new first entry. |
| 7240 Key& key = keys_[index]; | 7247 Key& key = keys_[index]; |
| 7241 key.map = map; | 7248 key.map = map; |
| 7242 key.name = internalized_name; | 7249 key.name = name; |
| 7243 field_offsets_[index] = field_offset; | 7250 field_offsets_[index] = field_offset; |
| 7244 } | |
| 7245 } | 7251 } |
| 7246 | 7252 |
| 7247 | 7253 |
| 7248 void KeyedLookupCache::Clear() { | 7254 void KeyedLookupCache::Clear() { |
| 7249 for (int index = 0; index < kLength; index++) keys_[index].map = NULL; | 7255 for (int index = 0; index < kLength; index++) keys_[index].map = NULL; |
| 7250 } | 7256 } |
| 7251 | 7257 |
| 7252 | 7258 |
| 7253 void DescriptorLookupCache::Clear() { | 7259 void DescriptorLookupCache::Clear() { |
| 7254 for (int index = 0; index < kLength; index++) keys_[index].source = NULL; | 7260 for (int index = 0; index < kLength; index++) keys_[index].source = NULL; |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7561 static_cast<int>(object_sizes_last_time_[index])); | 7567 static_cast<int>(object_sizes_last_time_[index])); |
| 7562 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) | 7568 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) |
| 7563 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7569 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
| 7564 | 7570 |
| 7565 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 7571 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
| 7566 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 7572 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
| 7567 ClearObjectStats(); | 7573 ClearObjectStats(); |
| 7568 } | 7574 } |
| 7569 | 7575 |
| 7570 } } // namespace v8::internal | 7576 } } // namespace v8::internal |
| OLD | NEW |