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 |