OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 2085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2096 // for example, JSArray::JSArrayVerify). | 2096 // for example, JSArray::JSArrayVerify). |
2097 obj->InitializeBody(map->instance_size()); | 2097 obj->InitializeBody(map->instance_size()); |
2098 } | 2098 } |
2099 | 2099 |
2100 | 2100 |
2101 Object* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) { | 2101 Object* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) { |
2102 // JSFunctions should be allocated using AllocateFunction to be | 2102 // JSFunctions should be allocated using AllocateFunction to be |
2103 // properly initialized. | 2103 // properly initialized. |
2104 ASSERT(map->instance_type() != JS_FUNCTION_TYPE); | 2104 ASSERT(map->instance_type() != JS_FUNCTION_TYPE); |
2105 | 2105 |
| 2106 // Both types of globla objects should be allocated using |
| 2107 // AllocateGloblaObject to be properly initialized. |
| 2108 ASSERT(map->instance_type() != JS_GLOBAL_OBJECT_TYPE); |
| 2109 ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE); |
| 2110 |
2106 // Allocate the backing storage for the properties. | 2111 // Allocate the backing storage for the properties. |
2107 int prop_size = map->unused_property_fields() - map->inobject_properties(); | 2112 int prop_size = map->unused_property_fields() - map->inobject_properties(); |
2108 Object* properties = AllocateFixedArray(prop_size, pretenure); | 2113 Object* properties = AllocateFixedArray(prop_size, pretenure); |
2109 if (properties->IsFailure()) return properties; | 2114 if (properties->IsFailure()) return properties; |
2110 | 2115 |
2111 // Allocate the JSObject. | 2116 // Allocate the JSObject. |
2112 AllocationSpace space = | 2117 AllocationSpace space = |
2113 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; | 2118 (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE; |
2114 if (map->instance_size() > MaxObjectSizeInPagedSpace()) space = LO_SPACE; | 2119 if (map->instance_size() > MaxObjectSizeInPagedSpace()) space = LO_SPACE; |
2115 Object* obj = Allocate(map, space); | 2120 Object* obj = Allocate(map, space); |
(...skipping 20 matching lines...) Expand all Loading... |
2136 Object* result = | 2141 Object* result = |
2137 AllocateJSObjectFromMap(constructor->initial_map(), pretenure); | 2142 AllocateJSObjectFromMap(constructor->initial_map(), pretenure); |
2138 // Make sure result is NOT a global object if valid. | 2143 // Make sure result is NOT a global object if valid. |
2139 ASSERT(result->IsFailure() || !result->IsGlobalObject()); | 2144 ASSERT(result->IsFailure() || !result->IsGlobalObject()); |
2140 return result; | 2145 return result; |
2141 } | 2146 } |
2142 | 2147 |
2143 | 2148 |
2144 Object* Heap::AllocateGlobalObject(JSFunction* constructor) { | 2149 Object* Heap::AllocateGlobalObject(JSFunction* constructor) { |
2145 ASSERT(constructor->has_initial_map()); | 2150 ASSERT(constructor->has_initial_map()); |
| 2151 Map* map = constructor->initial_map(); |
| 2152 |
2146 // Make sure no field properties are described in the initial map. | 2153 // Make sure no field properties are described in the initial map. |
2147 // This guarantees us that normalizing the properties does not | 2154 // This guarantees us that normalizing the properties does not |
2148 // require us to change property values to JSGlobalPropertyCells. | 2155 // require us to change property values to JSGlobalPropertyCells. |
2149 ASSERT(constructor->initial_map()->NextFreePropertyIndex() == 0); | 2156 ASSERT(map->NextFreePropertyIndex() == 0); |
2150 | 2157 |
2151 // Make sure we don't have a ton of pre-allocated slots in the | 2158 // Make sure we don't have a ton of pre-allocated slots in the |
2152 // global objects. They will be unused once we normalize the object. | 2159 // global objects. They will be unused once we normalize the object. |
2153 ASSERT(constructor->initial_map()->unused_property_fields() == 0); | 2160 ASSERT(map->unused_property_fields() == 0); |
2154 ASSERT(constructor->initial_map()->inobject_properties() == 0); | 2161 ASSERT(map->inobject_properties() == 0); |
2155 | 2162 |
2156 // Allocate the object based on the constructors initial map. | 2163 // Initial size of the backing store to avoid resize of the storage during |
2157 Object* result = AllocateJSObjectFromMap(constructor->initial_map(), TENURED); | 2164 // bootstrapping. The size differs between the JS global object ad the |
2158 if (result->IsFailure()) return result; | 2165 // builtins object. |
| 2166 int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512; |
2159 | 2167 |
2160 // Normalize the result. | 2168 // Allocate a dictionary object for backing storage. |
2161 JSObject* global = JSObject::cast(result); | 2169 Object* obj = |
2162 result = global->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); | 2170 StringDictionary::Allocate( |
2163 if (result->IsFailure()) return result; | 2171 map->NumberOfDescribedProperties() * 2 + initial_size); |
| 2172 if (obj->IsFailure()) return obj; |
| 2173 StringDictionary* dictionary = StringDictionary::cast(obj); |
| 2174 |
| 2175 // The global object might be created from an object template with accessors. |
| 2176 // Fill these accessors into the dictionary. |
| 2177 DescriptorArray* descs = map->instance_descriptors(); |
| 2178 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 2179 PropertyDetails details = descs->GetDetails(i); |
| 2180 ASSERT(details.type() == CALLBACKS); // Only accessors are expected. |
| 2181 PropertyDetails d = |
| 2182 PropertyDetails(details.attributes(), CALLBACKS, details.index()); |
| 2183 Object* value = descs->GetCallbacksObject(i); |
| 2184 value = Heap::AllocateJSGlobalPropertyCell(value); |
| 2185 if (value->IsFailure()) return value; |
| 2186 |
| 2187 Object* result = dictionary->Add(descs->GetKey(i), value, d); |
| 2188 if (result->IsFailure()) return result; |
| 2189 dictionary = StringDictionary::cast(result); |
| 2190 } |
| 2191 |
| 2192 // Allocate the global object and initialize it with the backing store. |
| 2193 obj = Allocate(map, OLD_POINTER_SPACE); |
| 2194 if (obj->IsFailure()) return obj; |
| 2195 JSObject* global = JSObject::cast(obj); |
| 2196 InitializeJSObjectFromMap(global, dictionary, map); |
| 2197 |
| 2198 // Create a new map for the global object. |
| 2199 obj = map->CopyDropDescriptors(); |
| 2200 if (obj->IsFailure()) return obj; |
| 2201 Map* new_map = Map::cast(obj); |
| 2202 |
| 2203 // Setup the global object as a normalized object. |
| 2204 global->set_map(new_map); |
| 2205 global->map()->set_instance_descriptors(Heap::empty_descriptor_array()); |
| 2206 global->set_properties(dictionary); |
2164 | 2207 |
2165 // Make sure result is a global object with properties in dictionary. | 2208 // Make sure result is a global object with properties in dictionary. |
2166 ASSERT(global->IsGlobalObject()); | 2209 ASSERT(global->IsGlobalObject()); |
2167 ASSERT(!global->HasFastProperties()); | 2210 ASSERT(!global->HasFastProperties()); |
2168 return global; | 2211 return global; |
2169 } | 2212 } |
2170 | 2213 |
2171 | 2214 |
2172 Object* Heap::CopyJSObject(JSObject* source) { | 2215 Object* Heap::CopyJSObject(JSObject* source) { |
2173 // Never used to copy functions. If functions need to be copied we | 2216 // Never used to copy functions. If functions need to be copied we |
(...skipping 1671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3845 #ifdef DEBUG | 3888 #ifdef DEBUG |
3846 bool Heap::GarbageCollectionGreedyCheck() { | 3889 bool Heap::GarbageCollectionGreedyCheck() { |
3847 ASSERT(FLAG_gc_greedy); | 3890 ASSERT(FLAG_gc_greedy); |
3848 if (Bootstrapper::IsActive()) return true; | 3891 if (Bootstrapper::IsActive()) return true; |
3849 if (disallow_allocation_failure()) return true; | 3892 if (disallow_allocation_failure()) return true; |
3850 return CollectGarbage(0, NEW_SPACE); | 3893 return CollectGarbage(0, NEW_SPACE); |
3851 } | 3894 } |
3852 #endif | 3895 #endif |
3853 | 3896 |
3854 } } // namespace v8::internal | 3897 } } // namespace v8::internal |
OLD | NEW |