Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/objects.cc

Issue 10444055: Promoting elements transitions to their own field. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: renaming SearchMode fields and moving it into descriptor array class Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 return result->holder()->GetPropertyWithCallback( 622 return result->holder()->GetPropertyWithCallback(
623 receiver, result->GetCallbackObject(), name); 623 receiver, result->GetCallbackObject(), name);
624 case HANDLER: 624 case HANDLER:
625 return result->proxy()->GetPropertyWithHandler(receiver, name); 625 return result->proxy()->GetPropertyWithHandler(receiver, name);
626 case INTERCEPTOR: { 626 case INTERCEPTOR: {
627 JSObject* recvr = JSObject::cast(receiver); 627 JSObject* recvr = JSObject::cast(receiver);
628 return result->holder()->GetPropertyWithInterceptor( 628 return result->holder()->GetPropertyWithInterceptor(
629 recvr, name, attributes); 629 recvr, name, attributes);
630 } 630 }
631 case MAP_TRANSITION: 631 case MAP_TRANSITION:
632 case ELEMENTS_TRANSITION:
633 case CONSTANT_TRANSITION: 632 case CONSTANT_TRANSITION:
634 case NULL_DESCRIPTOR: 633 case NULL_DESCRIPTOR:
635 break; 634 break;
636 } 635 }
637 UNREACHABLE(); 636 UNREACHABLE();
638 return NULL; 637 return NULL;
639 } 638 }
640 639
641 640
642 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { 641 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 } 1544 }
1546 } 1545 }
1547 1546
1548 // Only allow map transition if the object isn't the global object and there 1547 // Only allow map transition if the object isn't the global object and there
1549 // is not a transition for the name, or there's a transition for the name but 1548 // is not a transition for the name, or there's a transition for the name but
1550 // it's unrelated to properties. 1549 // it's unrelated to properties.
1551 int descriptor_index = old_descriptors->Search(name); 1550 int descriptor_index = old_descriptors->Search(name);
1552 1551
1553 // Element transitions are stored in the descriptor for property "", which is 1552 // Element transitions are stored in the descriptor for property "", which is
1554 // not a identifier and should have forced a switch to slow properties above. 1553 // not a identifier and should have forced a switch to slow properties above.
1555 ASSERT(descriptor_index == DescriptorArray::kNotFound || 1554 bool can_insert_transition = descriptor_index == DescriptorArray::kNotFound;
1556 old_descriptors->GetType(descriptor_index) != ELEMENTS_TRANSITION);
1557 bool can_insert_transition = descriptor_index == DescriptorArray::kNotFound ||
1558 old_descriptors->GetType(descriptor_index) == ELEMENTS_TRANSITION;
1559 bool allow_map_transition = 1555 bool allow_map_transition =
1560 can_insert_transition && 1556 can_insert_transition &&
1561 (isolate->context()->global_context()->object_function()->map() != map()); 1557 (isolate->context()->global_context()->object_function()->map() != map());
1562 1558
1563 ASSERT(index < map()->inobject_properties() || 1559 ASSERT(index < map()->inobject_properties() ||
1564 (index - map()->inobject_properties()) < properties()->length() || 1560 (index - map()->inobject_properties()) < properties()->length() ||
1565 map()->unused_property_fields() == 0); 1561 map()->unused_property_fields() == 0);
1566 // Allocate a new map for the object. 1562 // Allocate a new map for the object.
1567 Object* r; 1563 Object* r;
1568 { MaybeObject* maybe_r = map()->CopyDropDescriptors(); 1564 { MaybeObject* maybe_r = map()->CopyDropDescriptors();
(...skipping 25 matching lines...) Expand all
1594 properties()->CopySize(properties()->length() + kFieldsAdded); 1590 properties()->CopySize(properties()->length() + kFieldsAdded);
1595 if (!maybe_values->ToObject(&values)) return maybe_values; 1591 if (!maybe_values->ToObject(&values)) return maybe_values;
1596 } 1592 }
1597 set_properties(FixedArray::cast(values)); 1593 set_properties(FixedArray::cast(values));
1598 new_map->set_unused_property_fields(kFieldsAdded - 1); 1594 new_map->set_unused_property_fields(kFieldsAdded - 1);
1599 } else { 1595 } else {
1600 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); 1596 new_map->set_unused_property_fields(map()->unused_property_fields() - 1);
1601 } 1597 }
1602 // We have now allocated all the necessary objects. 1598 // We have now allocated all the necessary objects.
1603 // All the changes can be applied at once, so they are atomic. 1599 // All the changes can be applied at once, so they are atomic.
1604 map()->set_instance_descriptors(old_descriptors); 1600 if (allow_map_transition) {
1601 map()->set_instance_descriptors(old_descriptors);
1602 }
1605 new_map->SetBackPointer(map()); 1603 new_map->SetBackPointer(map());
1606 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); 1604 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
1607 set_map(new_map); 1605 set_map(new_map);
1608 return FastPropertyAtPut(index, value); 1606 return FastPropertyAtPut(index, value);
1609 } 1607 }
1610 1608
1611 1609
1612 MaybeObject* JSObject::AddConstantFunctionProperty( 1610 MaybeObject* JSObject::AddConstantFunctionProperty(
1613 String* name, 1611 String* name,
1614 JSFunction* function, 1612 JSFunction* function,
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
2121 return SetPropertyWithCallback(result.GetCallbackObject(), 2119 return SetPropertyWithCallback(result.GetCallbackObject(),
2122 name, value, result.holder(), strict_mode); 2120 name, value, result.holder(), strict_mode);
2123 } 2121 }
2124 case HANDLER: { 2122 case HANDLER: {
2125 return result.proxy()->SetPropertyViaPrototypesWithHandler( 2123 return result.proxy()->SetPropertyViaPrototypesWithHandler(
2126 this, name, value, attributes, strict_mode, done); 2124 this, name, value, attributes, strict_mode, done);
2127 } 2125 }
2128 case MAP_TRANSITION: 2126 case MAP_TRANSITION:
2129 case CONSTANT_TRANSITION: 2127 case CONSTANT_TRANSITION:
2130 case NULL_DESCRIPTOR: 2128 case NULL_DESCRIPTOR:
2131 case ELEMENTS_TRANSITION:
2132 break; 2129 break;
2133 } 2130 }
2134 } 2131 }
2135 2132
2136 // If we get here with *done true, we have encountered a read-only property. 2133 // If we get here with *done true, we have encountered a read-only property.
2137 if (*done) { 2134 if (*done) {
2138 if (strict_mode == kNonStrictMode) return value; 2135 if (strict_mode == kNonStrictMode) return value;
2139 Handle<Object> args[] = { Handle<Object>(name), Handle<Object>(this)}; 2136 Handle<Object> args[] = { Handle<Object>(name), Handle<Object>(this)};
2140 return isolate->Throw(*isolate->factory()->NewTypeError( 2137 return isolate->Throw(*isolate->factory()->NewTypeError(
2141 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); 2138 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 2188
2192 2189
2193 Handle<Map> Map::FindTransitionedMap(MapHandleList* candidates) { 2190 Handle<Map> Map::FindTransitionedMap(MapHandleList* candidates) {
2194 ElementsKind kind = elements_kind(); 2191 ElementsKind kind = elements_kind();
2195 Handle<Map> transitioned_map = Handle<Map>::null(); 2192 Handle<Map> transitioned_map = Handle<Map>::null();
2196 Handle<Map> current_map(this); 2193 Handle<Map> current_map(this);
2197 bool packed = IsFastPackedElementsKind(kind); 2194 bool packed = IsFastPackedElementsKind(kind);
2198 if (IsTransitionableFastElementsKind(kind)) { 2195 if (IsTransitionableFastElementsKind(kind)) {
2199 while (CanTransitionToMoreGeneralFastElementsKind(kind, false)) { 2196 while (CanTransitionToMoreGeneralFastElementsKind(kind, false)) {
2200 kind = GetNextMoreGeneralFastElementsKind(kind, false); 2197 kind = GetNextMoreGeneralFastElementsKind(kind, false);
2201 bool dummy = true;
2202 Handle<Map> maybe_transitioned_map = 2198 Handle<Map> maybe_transitioned_map =
2203 MaybeNull(current_map->LookupElementsTransitionMap(kind, &dummy)); 2199 MaybeNull(current_map->LookupElementsTransitionMap(kind));
2204 if (maybe_transitioned_map.is_null()) break; 2200 if (maybe_transitioned_map.is_null()) break;
2205 if (ContainsMap(candidates, maybe_transitioned_map) && 2201 if (ContainsMap(candidates, maybe_transitioned_map) &&
2206 (packed || !IsFastPackedElementsKind(kind))) { 2202 (packed || !IsFastPackedElementsKind(kind))) {
2207 transitioned_map = maybe_transitioned_map; 2203 transitioned_map = maybe_transitioned_map;
2208 if (!IsFastPackedElementsKind(kind)) packed = false; 2204 if (!IsFastPackedElementsKind(kind)) packed = false;
2209 } 2205 }
2210 current_map = maybe_transitioned_map; 2206 current_map = maybe_transitioned_map;
2211 } 2207 }
2212 } 2208 }
2213 return transitioned_map; 2209 return transitioned_map;
2214 } 2210 }
2215 2211
2216 2212
2217 static Map* GetElementsTransitionMapFromDescriptor(Object* descriptor_contents, 2213 static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
2218 ElementsKind elements_kind) { 2214 Map* current_map = map;
2219 if (descriptor_contents->IsMap()) { 2215 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind());
2220 Map* map = Map::cast(descriptor_contents); 2216 int to_index = GetSequenceIndexFromFastElementsKind(to_kind);
2221 if (map->elements_kind() == elements_kind) { 2217 for (; index < to_index; ++index) {
2222 return map; 2218 Map* next_map = current_map->elements_transition_map();
2219 if (next_map == NULL) {
2220 return current_map;
2223 } 2221 }
2224 return NULL; 2222 current_map = next_map;
2225 } 2223 }
2226 2224 ASSERT(current_map->elements_kind() == to_kind);
2227 FixedArray* map_array = FixedArray::cast(descriptor_contents); 2225 return current_map;
2228 for (int i = 0; i < map_array->length(); ++i) {
2229 Object* current = map_array->get(i);
2230 // Skip undefined slots, they are sentinels for reclaimed maps.
2231 if (!current->IsUndefined()) {
2232 Map* current_map = Map::cast(map_array->get(i));
2233 if (current_map->elements_kind() == elements_kind) {
2234 return current_map;
2235 }
2236 }
2237 }
2238
2239 return NULL;
2240 } 2226 }
2241 2227
2242 2228
2243 static MaybeObject* AddElementsTransitionMapToDescriptor( 2229 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) {
2244 Object* descriptor_contents, 2230 if (this->instance_descriptors()->MayContainTransitions() &&
2245 Map* new_map) { 2231 IsMoreGeneralElementsKindTransition(this->elements_kind(), to_kind)) {
2246 // Nothing was in the descriptor for an ELEMENTS_TRANSITION, 2232 Map* to_map = FindClosestElementsTransition(this, to_kind);
2247 // simply add the map. 2233 if (to_map->elements_kind() == to_kind) {
2248 if (descriptor_contents == NULL) { 2234 return to_map;
2249 return new_map;
2250 }
2251
2252 // There was already a map in the descriptor, create a 2-element FixedArray
2253 // to contain the existing map plus the new one.
2254 FixedArray* new_array;
2255 Heap* heap = new_map->GetHeap();
2256 if (descriptor_contents->IsMap()) {
2257 // Must tenure, DescriptorArray expects no new-space objects.
2258 MaybeObject* maybe_new_array = heap->AllocateFixedArray(2, TENURED);
2259 if (!maybe_new_array->To<FixedArray>(&new_array)) {
2260 return maybe_new_array;
2261 }
2262 new_array->set(0, descriptor_contents);
2263 new_array->set(1, new_map);
2264 return new_array;
2265 }
2266
2267 // The descriptor already contained a list of maps for different ElementKinds
2268 // of ELEMENTS_TRANSITION, first check the existing array for an undefined
2269 // slot, and if that's not available, create a FixedArray to hold the existing
2270 // maps plus the new one and fill it in.
2271 FixedArray* array = FixedArray::cast(descriptor_contents);
2272 for (int i = 0; i < array->length(); ++i) {
2273 if (array->get(i)->IsUndefined()) {
2274 array->set(i, new_map);
2275 return array;
2276 }
2277 }
2278
2279 // Must tenure, DescriptorArray expects no new-space objects.
2280 MaybeObject* maybe_new_array =
2281 heap->AllocateFixedArray(array->length() + 1, TENURED);
2282 if (!maybe_new_array->To<FixedArray>(&new_array)) {
2283 return maybe_new_array;
2284 }
2285 int i = 0;
2286 while (i < array->length()) {
2287 new_array->set(i, array->get(i));
2288 ++i;
2289 }
2290 new_array->set(i, new_map);
2291 return new_array;
2292 }
2293
2294
2295 String* Map::elements_transition_sentinel_name() {
2296 return GetHeap()->empty_symbol();
2297 }
2298
2299
2300 Object* Map::GetDescriptorContents(String* sentinel_name,
2301 bool* safe_to_add_transition) {
2302 // Get the cached index for the descriptors lookup, or find and cache it.
2303 DescriptorArray* descriptors = instance_descriptors();
2304 DescriptorLookupCache* cache = GetIsolate()->descriptor_lookup_cache();
2305 int index = cache->Lookup(descriptors, sentinel_name);
2306 if (index == DescriptorLookupCache::kAbsent) {
2307 index = descriptors->Search(sentinel_name);
2308 cache->Update(descriptors, sentinel_name, index);
2309 }
2310 // If the transition already exists, return its descriptor.
2311 if (index != DescriptorArray::kNotFound) {
2312 PropertyDetails details = descriptors->GetDetails(index);
2313 if (details.type() == ELEMENTS_TRANSITION) {
2314 return descriptors->GetValue(index);
2315 } else {
2316 if (safe_to_add_transition != NULL) {
2317 *safe_to_add_transition = false;
2318 }
2319 } 2235 }
2320 } 2236 }
2321 return NULL; 2237 return NULL;
2322 } 2238 }
2323 2239
2324 2240
2325 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind, 2241 MaybeObject* Map::CreateNextElementsTransition(ElementsKind next_kind) {
2326 bool* safe_to_add_transition) { 2242 ASSERT(elements_transition_map() == NULL);
2327 ElementsKind from_kind = elements_kind(); 2243 ASSERT(GetSequenceIndexFromFastElementsKind(elements_kind()) ==
2328 if (IsFastElementsKind(from_kind) && IsFastElementsKind(to_kind)) { 2244 (GetSequenceIndexFromFastElementsKind(next_kind) - 1));
2329 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
2330 if (safe_to_add_transition) *safe_to_add_transition = false;
2331 return NULL;
2332 }
2333 ElementsKind transitioned_from_kind =
2334 GetNextMoreGeneralFastElementsKind(from_kind, false);
2335 2245
2246 Map* next_map;
2247 MaybeObject* maybe_next_map =
2248 this->CopyDropTransitions(DescriptorArray::CANNOT_BE_SHARED);
2249 if (!maybe_next_map->To(&next_map)) return maybe_next_map;
2336 2250
2337 // If the transition is a single step in the transition sequence, fall 2251 next_map->set_elements_kind(next_kind);
2338 // through to looking it up and returning it. If it requires several steps, 2252 next_map->SetBackPointer(this);
2339 // divide and conquer. 2253 this->set_elements_transition_map(next_map);
2340 if (transitioned_from_kind != to_kind) { 2254 return next_map;
2341 // If the transition is several steps in the lattice, divide and conquer.
2342 Map* from_map = LookupElementsTransitionMap(transitioned_from_kind,
2343 safe_to_add_transition);
2344 if (from_map == NULL) return NULL;
2345 return from_map->LookupElementsTransitionMap(to_kind,
2346 safe_to_add_transition);
2347 }
2348 }
2349 Object* descriptor_contents = GetDescriptorContents(
2350 elements_transition_sentinel_name(), safe_to_add_transition);
2351 if (descriptor_contents != NULL) {
2352 Map* maybe_transition_map =
2353 GetElementsTransitionMapFromDescriptor(descriptor_contents,
2354 to_kind);
2355 ASSERT(maybe_transition_map == NULL || maybe_transition_map->IsMap());
2356 return maybe_transition_map;
2357 }
2358 return NULL;
2359 } 2255 }
2360 2256
2361 2257
2362 MaybeObject* Map::AddElementsTransition(ElementsKind to_kind, 2258 static MaybeObject* AddMissingElementsTransitions(Map* map,
2363 Map* transitioned_map) { 2259 ElementsKind to_kind) {
2364 ElementsKind from_kind = elements_kind(); 2260 int index = GetSequenceIndexFromFastElementsKind(map->elements_kind()) + 1;
2365 if (IsFastElementsKind(from_kind) && IsFastElementsKind(to_kind)) { 2261 int to_index = GetSequenceIndexFromFastElementsKind(to_kind);
2366 ASSERT(IsMoreGeneralElementsKindTransition(from_kind, to_kind)); 2262 ASSERT(index <= to_index);
2367 ElementsKind transitioned_from_kind =
2368 GetNextMoreGeneralFastElementsKind(from_kind, false);
2369 // The map transitions graph should be a tree, therefore transitions to
2370 // ElementsKind that are not adjacent in the ElementsKind sequence are not
2371 // done directly, but instead by going through intermediate ElementsKinds
2372 // first.
2373 if (to_kind != transitioned_from_kind) {
2374 bool safe_to_add = true;
2375 Map* intermediate_map = LookupElementsTransitionMap(
2376 transitioned_from_kind, &safe_to_add);
2377 // This method is only called when safe_to_add has been found to be true
2378 // earlier.
2379 ASSERT(safe_to_add);
2380 2263
2381 if (intermediate_map == NULL) { 2264 Map* current_map = map;
2382 MaybeObject* maybe_map = CopyDropTransitions(); 2265
2383 if (!maybe_map->To(&intermediate_map)) return maybe_map; 2266 for (; index <= to_index; ++index) {
2384 intermediate_map->set_elements_kind(transitioned_from_kind); 2267 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index);
2385 MaybeObject* maybe_transition = AddElementsTransition( 2268 MaybeObject* maybe_next_map =
2386 transitioned_from_kind, intermediate_map); 2269 current_map->CreateNextElementsTransition(next_kind);
2387 if (maybe_transition->IsFailure()) return maybe_transition; 2270 if (!maybe_next_map->To(&current_map)) return maybe_next_map;
2388 }
2389 return intermediate_map->AddElementsTransition(to_kind, transitioned_map);
2390 }
2391 } 2271 }
2392 2272
2393 bool safe_to_add_transition = true; 2273 ASSERT(current_map->elements_kind() == to_kind);
2394 Object* descriptor_contents = GetDescriptorContents( 2274 return current_map;
2395 elements_transition_sentinel_name(), &safe_to_add_transition);
2396 // This method is only called when safe_to_add_transition has been found
2397 // to be true earlier.
2398 ASSERT(safe_to_add_transition);
2399 MaybeObject* maybe_new_contents =
2400 AddElementsTransitionMapToDescriptor(descriptor_contents,
2401 transitioned_map);
2402 Object* new_contents;
2403 if (!maybe_new_contents->ToObject(&new_contents)) {
2404 return maybe_new_contents;
2405 }
2406
2407 ElementsTransitionDescriptor desc(elements_transition_sentinel_name(),
2408 new_contents);
2409 Object* new_descriptors;
2410 MaybeObject* maybe_new_descriptors =
2411 instance_descriptors()->CopyInsert(&desc, KEEP_TRANSITIONS);
2412 if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
2413 return maybe_new_descriptors;
2414 }
2415 set_instance_descriptors(DescriptorArray::cast(new_descriptors));
2416 transitioned_map->SetBackPointer(this);
2417 return this;
2418 } 2275 }
2419 2276
2420 2277
2421 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, 2278 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
2422 ElementsKind to_kind) { 2279 ElementsKind to_kind) {
2423 Isolate* isolate = object->GetIsolate(); 2280 Isolate* isolate = object->GetIsolate();
2424 CALL_HEAP_FUNCTION(isolate, 2281 CALL_HEAP_FUNCTION(isolate,
2425 object->GetElementsTransitionMap(isolate, to_kind), 2282 object->GetElementsTransitionMap(isolate, to_kind),
2426 Map); 2283 Map);
2427 } 2284 }
2428 2285
2429 2286
2287 // If the map is using the empty descriptor array, install a new empty
2288 // descriptor array that will contain an element transition.
2289 // TODO(verwaest) Goes away once the descriptor array is immutable.
2290 static MaybeObject* EnsureMayContainTransitions(Map* map) {
2291 if (map->instance_descriptors()->MayContainTransitions()) return map;
2292 DescriptorArray* descriptor_array;
2293 MaybeObject* maybe_descriptor_array =
2294 DescriptorArray::Allocate(0, DescriptorArray::CANNOT_BE_SHARED);
2295 if (!maybe_descriptor_array->To(&descriptor_array)) {
2296 return maybe_descriptor_array;
2297 }
2298 map->set_instance_descriptors(descriptor_array);
2299 return map;
2300 }
2301
2302
2430 MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) { 2303 MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) {
2431 Map* current_map = map(); 2304 Map* start_map = map();
2432 ElementsKind from_kind = current_map->elements_kind(); 2305 ElementsKind from_kind = start_map->elements_kind();
2433 2306
2434 if (from_kind == to_kind) return current_map; 2307 if (from_kind == to_kind) {
2435 2308 return start_map;
2436 // Only objects with FastProperties can have DescriptorArrays and can track
2437 // element-related maps. Also don't add descriptors to maps that are shared.
2438 bool safe_to_add_transition = HasFastProperties() &&
2439 !current_map->IsUndefined() &&
2440 !current_map->is_shared();
2441
2442 // Prevent long chains of DICTIONARY -> FAST_*_ELEMENTS maps caused by objects
2443 // with elements that switch back and forth between dictionary and fast
2444 // element modes.
2445 if (from_kind == DICTIONARY_ELEMENTS &&
2446 IsFastElementsKind(to_kind)) {
2447 safe_to_add_transition = false;
2448 } 2309 }
2449 2310
2450 if (safe_to_add_transition) { 2311 Context* global_context = GetIsolate()->context()->global_context();
2451 // It's only safe to manipulate the descriptor array if it would be 2312 bool allow_store_transition =
2452 // safe to add a transition. 2313 // Only remember the map transition if the object's map is NOT equal to
2453 Map* maybe_transition_map = current_map->LookupElementsTransitionMap( 2314 // the global object_function's map and there is not an already existing
2454 to_kind, &safe_to_add_transition); 2315 // non-matching element transition.
2455 if (maybe_transition_map != NULL) { 2316 (global_context->object_function()->map() != map()) &&
2456 return maybe_transition_map; 2317 !start_map->IsUndefined() && !start_map->is_shared() &&
2457 } 2318 // Only store fast element maps in ascending generality.
2319 IsTransitionableFastElementsKind(from_kind) &&
2320 IsFastElementsKind(to_kind) &&
2321 IsMoreGeneralElementsKindTransition(from_kind, to_kind);
2322
2323 if (!allow_store_transition) {
2324 // Create a new free-floating map only if we are not allowed to store it.
2325 Map* new_map = NULL;
2326 MaybeObject* maybe_new_map =
2327 start_map->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
2328 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
2329 new_map->set_elements_kind(to_kind);
2330 return new_map;
2458 } 2331 }
2459 2332
2460 Map* new_map = NULL; 2333 EnsureMayContainTransitions(start_map);
2334 Map* closest_map = FindClosestElementsTransition(start_map, to_kind);
2461 2335
2462 // No transition to an existing map for the given ElementsKind. Make a new 2336 if (closest_map->elements_kind() == to_kind) {
2463 // one. 2337 return closest_map;
2464 { MaybeObject* maybe_map = current_map->CopyDropTransitions();
2465 if (!maybe_map->To(&new_map)) return maybe_map;
2466 } 2338 }
2467 2339
2468 new_map->set_elements_kind(to_kind); 2340 return AddMissingElementsTransitions(closest_map, to_kind);
2469
2470 // Only remember the map transition if the object's map is NOT equal to the
2471 // global object_function's map and there is not an already existing
2472 // non-matching element transition.
2473 Context* global_context = GetIsolate()->context()->global_context();
2474 bool allow_map_transition = safe_to_add_transition &&
2475 (global_context->object_function()->map() != map());
2476 if (allow_map_transition) {
2477 MaybeObject* maybe_transition =
2478 current_map->AddElementsTransition(to_kind, new_map);
2479 if (maybe_transition->IsFailure()) return maybe_transition;
2480 }
2481 return new_map;
2482 } 2341 }
2483 2342
2484 2343
2485 void JSObject::LocalLookupRealNamedProperty(String* name, 2344 void JSObject::LocalLookupRealNamedProperty(String* name,
2486 LookupResult* result) { 2345 LookupResult* result) {
2487 if (IsJSGlobalProxy()) { 2346 if (IsJSGlobalProxy()) {
2488 Object* proto = GetPrototype(); 2347 Object* proto = GetPrototype();
2489 if (proto->IsNull()) return result->NotFound(); 2348 if (proto->IsNull()) return result->NotFound();
2490 ASSERT(proto->IsJSGlobalObject()); 2349 ASSERT(proto->IsJSGlobalObject());
2491 // A GlobalProxy's prototype should always be a proper JSObject. 2350 // A GlobalProxy's prototype should always be a proper JSObject.
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
3008 JSFunction::cast(target_descriptors->GetValue(number)); 2867 JSFunction::cast(target_descriptors->GetValue(number));
3009 if (value == function) { 2868 if (value == function) {
3010 set_map(target_map); 2869 set_map(target_map);
3011 return value; 2870 return value;
3012 } 2871 }
3013 // Otherwise, replace with a MAP_TRANSITION to a new map with a 2872 // Otherwise, replace with a MAP_TRANSITION to a new map with a
3014 // FIELD, even if the value is a constant function. 2873 // FIELD, even if the value is a constant function.
3015 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); 2874 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
3016 } 2875 }
3017 case NULL_DESCRIPTOR: 2876 case NULL_DESCRIPTOR:
3018 case ELEMENTS_TRANSITION:
3019 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); 2877 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
3020 case HANDLER: 2878 case HANDLER:
3021 UNREACHABLE(); 2879 UNREACHABLE();
3022 return value; 2880 return value;
3023 } 2881 }
3024 UNREACHABLE(); // keep the compiler happy 2882 UNREACHABLE(); // keep the compiler happy
3025 return value; 2883 return value;
3026 } 2884 }
3027 2885
3028 2886
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3106 // Preserve the attributes of this existing property. 2964 // Preserve the attributes of this existing property.
3107 attributes = result.GetAttributes(); 2965 attributes = result.GetAttributes();
3108 return ConvertDescriptorToField(name, value, attributes); 2966 return ConvertDescriptorToField(name, value, attributes);
3109 case CALLBACKS: 2967 case CALLBACKS:
3110 case INTERCEPTOR: 2968 case INTERCEPTOR:
3111 // Override callback in clone 2969 // Override callback in clone
3112 return ConvertDescriptorToField(name, value, attributes); 2970 return ConvertDescriptorToField(name, value, attributes);
3113 case CONSTANT_TRANSITION: 2971 case CONSTANT_TRANSITION:
3114 // Replace with a MAP_TRANSITION to a new map with a FIELD, even 2972 // Replace with a MAP_TRANSITION to a new map with a FIELD, even
3115 // if the value is a function. 2973 // if the value is a function.
3116 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
3117 case NULL_DESCRIPTOR: 2974 case NULL_DESCRIPTOR:
3118 case ELEMENTS_TRANSITION:
3119 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); 2975 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
3120 case HANDLER: 2976 case HANDLER:
3121 UNREACHABLE(); 2977 UNREACHABLE();
3122 } 2978 }
3123 UNREACHABLE(); // keep the compiler happy 2979 UNREACHABLE(); // keep the compiler happy
3124 return value; 2980 return value;
3125 } 2981 }
3126 2982
3127 2983
3128 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor( 2984 PropertyAttributes JSObject::GetPropertyAttributePostInterceptor(
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
3399 } 3255 }
3400 MaybeObject* maybe_dictionary = 3256 MaybeObject* maybe_dictionary =
3401 dictionary->Add(descs->GetKey(i), value, details); 3257 dictionary->Add(descs->GetKey(i), value, details);
3402 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 3258 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
3403 break; 3259 break;
3404 } 3260 }
3405 case MAP_TRANSITION: 3261 case MAP_TRANSITION:
3406 case CONSTANT_TRANSITION: 3262 case CONSTANT_TRANSITION:
3407 case NULL_DESCRIPTOR: 3263 case NULL_DESCRIPTOR:
3408 case INTERCEPTOR: 3264 case INTERCEPTOR:
3409 case ELEMENTS_TRANSITION:
3410 break; 3265 break;
3411 case HANDLER: 3266 case HANDLER:
3412 case NORMAL: 3267 case NORMAL:
3413 UNREACHABLE(); 3268 UNREACHABLE();
3414 break; 3269 break;
3415 } 3270 }
3416 } 3271 }
3417 3272
3418 Heap* current_heap = GetHeap(); 3273 Heap* current_heap = GetHeap();
3419 3274
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
4185 { MaybeObject* maybe = NormalizeElements(); 4040 { MaybeObject* maybe = NormalizeElements();
4186 if (!maybe->To<SeededNumberDictionary>(&dictionary)) return maybe; 4041 if (!maybe->To<SeededNumberDictionary>(&dictionary)) return maybe;
4187 } 4042 }
4188 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 4043 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
4189 // Make sure that we never go back to fast case. 4044 // Make sure that we never go back to fast case.
4190 dictionary->set_requires_slow_elements(); 4045 dictionary->set_requires_slow_elements();
4191 4046
4192 // Do a map transition, other objects with this map may still 4047 // Do a map transition, other objects with this map may still
4193 // be extensible. 4048 // be extensible.
4194 Map* new_map; 4049 Map* new_map;
4195 { MaybeObject* maybe = map()->CopyDropTransitions(); 4050 { MaybeObject* maybe =
4051 map()->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
4196 if (!maybe->To<Map>(&new_map)) return maybe; 4052 if (!maybe->To<Map>(&new_map)) return maybe;
4197 } 4053 }
4198 new_map->set_is_extensible(false); 4054 new_map->set_is_extensible(false);
4199 set_map(new_map); 4055 set_map(new_map);
4200 ASSERT(!map()->is_extensible()); 4056 ASSERT(!map()->is_extensible());
4201 return new_map; 4057 return new_map;
4202 } 4058 }
4203 4059
4204 4060
4205 // Tests for the fast common case for property enumeration: 4061 // Tests for the fast common case for property enumeration:
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after
4965 Map::cast(result)->set_inobject_properties(inobject_properties()); 4821 Map::cast(result)->set_inobject_properties(inobject_properties());
4966 Map::cast(result)->set_unused_property_fields(unused_property_fields()); 4822 Map::cast(result)->set_unused_property_fields(unused_property_fields());
4967 4823
4968 // If the map has pre-allocated properties always start out with a descriptor 4824 // If the map has pre-allocated properties always start out with a descriptor
4969 // array describing these properties. 4825 // array describing these properties.
4970 if (pre_allocated_property_fields() > 0) { 4826 if (pre_allocated_property_fields() > 0) {
4971 ASSERT(constructor()->IsJSFunction()); 4827 ASSERT(constructor()->IsJSFunction());
4972 JSFunction* ctor = JSFunction::cast(constructor()); 4828 JSFunction* ctor = JSFunction::cast(constructor());
4973 Object* descriptors; 4829 Object* descriptors;
4974 { MaybeObject* maybe_descriptors = 4830 { MaybeObject* maybe_descriptors =
4975 ctor->initial_map()->instance_descriptors()->RemoveTransitions(); 4831 ctor->initial_map()->instance_descriptors()->RemoveTransitions(
4832 DescriptorArray::MAY_BE_SHARED);
4976 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors; 4833 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors;
4977 } 4834 }
4978 Map::cast(result)->set_instance_descriptors( 4835 Map::cast(result)->set_instance_descriptors(
4979 DescriptorArray::cast(descriptors)); 4836 DescriptorArray::cast(descriptors));
4980 Map::cast(result)->set_pre_allocated_property_fields( 4837 Map::cast(result)->set_pre_allocated_property_fields(
4981 pre_allocated_property_fields()); 4838 pre_allocated_property_fields());
4982 } 4839 }
4983 Map::cast(result)->set_bit_field(bit_field()); 4840 Map::cast(result)->set_bit_field(bit_field());
4984 Map::cast(result)->set_bit_field2(bit_field2()); 4841 Map::cast(result)->set_bit_field2(bit_field2());
4985 Map::cast(result)->set_bit_field3(bit_field3()); 4842 Map::cast(result)->set_bit_field3(bit_field3());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5018 #ifdef DEBUG 4875 #ifdef DEBUG
5019 if (FLAG_verify_heap && Map::cast(result)->is_shared()) { 4876 if (FLAG_verify_heap && Map::cast(result)->is_shared()) {
5020 Map::cast(result)->SharedMapVerify(); 4877 Map::cast(result)->SharedMapVerify();
5021 } 4878 }
5022 #endif 4879 #endif
5023 4880
5024 return result; 4881 return result;
5025 } 4882 }
5026 4883
5027 4884
5028 MaybeObject* Map::CopyDropTransitions() { 4885 MaybeObject* Map::CopyDropTransitions(
4886 DescriptorArray::SharedMode shared_mode) {
5029 Object* new_map; 4887 Object* new_map;
5030 { MaybeObject* maybe_new_map = CopyDropDescriptors(); 4888 { MaybeObject* maybe_new_map = CopyDropDescriptors();
5031 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 4889 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
5032 } 4890 }
5033 Object* descriptors; 4891 Object* descriptors;
5034 { MaybeObject* maybe_descriptors = 4892 { MaybeObject* maybe_descriptors =
5035 instance_descriptors()->RemoveTransitions(); 4893 instance_descriptors()->RemoveTransitions(shared_mode);
5036 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors; 4894 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors;
5037 } 4895 }
5038 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); 4896 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors));
5039 return new_map; 4897 return new_map;
5040 } 4898 }
5041 4899
5042 void Map::UpdateCodeCache(Handle<Map> map, 4900 void Map::UpdateCodeCache(Handle<Map> map,
5043 Handle<String> name, 4901 Handle<String> name,
5044 Handle<Code> code) { 4902 Handle<Code> code) {
5045 Isolate* isolate = map->GetIsolate(); 4903 Isolate* isolate = map->GetIsolate();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
5091 4949
5092 // An iterator over all map transitions in an descriptor array, reusing the map 4950 // An iterator over all map transitions in an descriptor array, reusing the map
5093 // field of the contens array while it is running. 4951 // field of the contens array while it is running.
5094 class IntrusiveMapTransitionIterator { 4952 class IntrusiveMapTransitionIterator {
5095 public: 4953 public:
5096 explicit IntrusiveMapTransitionIterator(DescriptorArray* descriptor_array) 4954 explicit IntrusiveMapTransitionIterator(DescriptorArray* descriptor_array)
5097 : descriptor_array_(descriptor_array) { } 4955 : descriptor_array_(descriptor_array) { }
5098 4956
5099 void Start() { 4957 void Start() {
5100 ASSERT(!IsIterating()); 4958 ASSERT(!IsIterating());
5101 if (HasDescriptors()) *DescriptorArrayHeader() = Smi::FromInt(0); 4959 if (descriptor_array_->MayContainTransitions())
4960 *DescriptorArrayHeader() = Smi::FromInt(0);
5102 } 4961 }
5103 4962
5104 bool IsIterating() { 4963 bool IsIterating() {
5105 return HasDescriptors() && (*DescriptorArrayHeader())->IsSmi(); 4964 return descriptor_array_->MayContainTransitions() &&
4965 (*DescriptorArrayHeader())->IsSmi();
5106 } 4966 }
5107 4967
5108 Map* Next() { 4968 Map* Next() {
5109 ASSERT(IsIterating()); 4969 ASSERT(IsIterating());
5110 // Attention, tricky index manipulation ahead: Two consecutive indices are 4970 // Attention, tricky index manipulation ahead: Two consecutive indices are
5111 // assigned to each descriptor. Most descriptors directly advance to the 4971 // assigned to each descriptor. Most descriptors directly advance to the
5112 // next descriptor by adding 2 to the index. The exceptions are the 4972 // next descriptor by adding 2 to the index. The exceptions are the
5113 // CALLBACKS entries: An even index means we look at its getter, and an odd 4973 // CALLBACKS entries: An even index means we look at its getter, and an odd
5114 // index means we look at its setter. 4974 // index means we look at its setter.
5115 int raw_index = Smi::cast(*DescriptorArrayHeader())->value(); 4975 int raw_index = Smi::cast(*DescriptorArrayHeader())->value();
5116 int index = raw_index / 2; 4976 int index = raw_index / 2;
5117 int number_of_descriptors = descriptor_array_->number_of_descriptors(); 4977 int number_of_descriptors = descriptor_array_->number_of_descriptors();
5118 while (index < number_of_descriptors) { 4978 while (index < number_of_descriptors) {
5119 PropertyDetails details(descriptor_array_->GetDetails(index)); 4979 PropertyDetails details(descriptor_array_->GetDetails(index));
5120 switch (details.type()) { 4980 switch (details.type()) {
5121 case MAP_TRANSITION: 4981 case MAP_TRANSITION:
5122 case CONSTANT_TRANSITION: 4982 case CONSTANT_TRANSITION:
5123 case ELEMENTS_TRANSITION:
5124 // We definitely have a map transition. 4983 // We definitely have a map transition.
5125 *DescriptorArrayHeader() = Smi::FromInt(raw_index + 2); 4984 *DescriptorArrayHeader() = Smi::FromInt(raw_index + 2);
5126 return static_cast<Map*>(descriptor_array_->GetValue(index)); 4985 return static_cast<Map*>(descriptor_array_->GetValue(index));
5127 case CALLBACKS: { 4986 case CALLBACKS: {
5128 // We might have a map transition in a getter or in a setter. 4987 // We might have a map transition in a getter or in a setter.
5129 AccessorPair* accessors = 4988 AccessorPair* accessors =
5130 static_cast<AccessorPair*>(descriptor_array_->GetValue(index)); 4989 static_cast<AccessorPair*>(descriptor_array_->GetValue(index));
5131 Object* accessor; 4990 Object* accessor;
5132 if ((raw_index & 1) == 0) { 4991 if ((raw_index & 1) == 0) {
5133 accessor = accessors->setter(); 4992 accessor = accessors->setter();
(...skipping 13 matching lines...) Expand all
5147 case CONSTANT_FUNCTION: 5006 case CONSTANT_FUNCTION:
5148 case HANDLER: 5007 case HANDLER:
5149 case INTERCEPTOR: 5008 case INTERCEPTOR:
5150 case NULL_DESCRIPTOR: 5009 case NULL_DESCRIPTOR:
5151 // We definitely have no map transition. 5010 // We definitely have no map transition.
5152 raw_index += 2; 5011 raw_index += 2;
5153 ++index; 5012 ++index;
5154 break; 5013 break;
5155 } 5014 }
5156 } 5015 }
5016 if (index == descriptor_array_->number_of_descriptors()) {
5017 Map* elements_transition = descriptor_array_->elements_transition_map();
5018 if (elements_transition != NULL) {
5019 *DescriptorArrayHeader() = Smi::FromInt(index + 1);
5020 return elements_transition;
5021 }
5022 }
5157 *DescriptorArrayHeader() = descriptor_array_->GetHeap()->fixed_array_map(); 5023 *DescriptorArrayHeader() = descriptor_array_->GetHeap()->fixed_array_map();
5158 return NULL; 5024 return NULL;
5159 } 5025 }
5160 5026
5161 private: 5027 private:
5162 bool HasDescriptors() {
5163 return descriptor_array_->length() > DescriptorArray::kFirstIndex;
5164 }
5165
5166 Object** DescriptorArrayHeader() { 5028 Object** DescriptorArrayHeader() {
5167 return HeapObject::RawField(descriptor_array_, DescriptorArray::kMapOffset); 5029 return HeapObject::RawField(descriptor_array_, DescriptorArray::kMapOffset);
5168 } 5030 }
5169 5031
5170 DescriptorArray* descriptor_array_; 5032 DescriptorArray* descriptor_array_;
5171 }; 5033 };
5172 5034
5173 5035
5174 // An iterator over all prototype transitions, reusing the map field of the 5036 // An iterator over all prototype transitions, reusing the map field of the
5175 // underlying array while it is running. 5037 // underlying array while it is running.
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
5844 bool FixedArray::IsEqualTo(FixedArray* other) { 5706 bool FixedArray::IsEqualTo(FixedArray* other) {
5845 if (length() != other->length()) return false; 5707 if (length() != other->length()) return false;
5846 for (int i = 0 ; i < length(); ++i) { 5708 for (int i = 0 ; i < length(); ++i) {
5847 if (get(i) != other->get(i)) return false; 5709 if (get(i) != other->get(i)) return false;
5848 } 5710 }
5849 return true; 5711 return true;
5850 } 5712 }
5851 #endif 5713 #endif
5852 5714
5853 5715
5854 MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) { 5716 MaybeObject* DescriptorArray::Allocate(int number_of_descriptors,
5717 SharedMode shared_mode) {
5855 Heap* heap = Isolate::Current()->heap(); 5718 Heap* heap = Isolate::Current()->heap();
5719 // Do not use DescriptorArray::cast on incomplete object.
5720 FixedArray* result;
5856 if (number_of_descriptors == 0) { 5721 if (number_of_descriptors == 0) {
5857 return heap->empty_descriptor_array(); 5722 if (shared_mode == MAY_BE_SHARED) {
5723 return heap->empty_descriptor_array();
5724 }
5725 { MaybeObject* maybe_array =
5726 heap->AllocateFixedArray(kTransitionsIndex + 1);
5727 if (!maybe_array->To(&result)) return maybe_array;
5728 }
5729 } else {
5730 // Allocate the array of keys.
5731 { MaybeObject* maybe_array =
5732 heap->AllocateFixedArray(ToKeyIndex(number_of_descriptors));
5733 if (!maybe_array->To(&result)) return maybe_array;
5734 }
5735 result->set(kEnumerationIndexIndex,
5736 Smi::FromInt(PropertyDetails::kInitialIndex));
5858 } 5737 }
5859 // Allocate the array of keys.
5860 Object* array;
5861 { MaybeObject* maybe_array =
5862 heap->AllocateFixedArray(ToKeyIndex(number_of_descriptors));
5863 if (!maybe_array->ToObject(&array)) return maybe_array;
5864 }
5865 // Do not use DescriptorArray::cast on incomplete object.
5866 FixedArray* result = FixedArray::cast(array);
5867
5868 result->set(kBitField3StorageIndex, Smi::FromInt(0)); 5738 result->set(kBitField3StorageIndex, Smi::FromInt(0));
5869 result->set(kEnumerationIndexIndex, 5739 result->set(kTransitionsIndex, Smi::FromInt(0));
5870 Smi::FromInt(PropertyDetails::kInitialIndex));
5871 return result; 5740 return result;
5872 } 5741 }
5873 5742
5874 5743
5875 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, 5744 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
5876 FixedArray* new_cache, 5745 FixedArray* new_cache,
5877 Object* new_index_cache) { 5746 Object* new_index_cache) {
5878 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); 5747 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength);
5879 ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray()); 5748 ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray());
5880 if (HasEnumCache()) { 5749 if (HasEnumCache()) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
5962 // We are replacing an existing descriptor. We keep the enumeration index 5831 // We are replacing an existing descriptor. We keep the enumeration index
5963 // of a visible property. 5832 // of a visible property.
5964 keep_enumeration_index = true; 5833 keep_enumeration_index = true;
5965 } else if (remove_transitions) { 5834 } else if (remove_transitions) {
5966 // Replaced descriptor has been counted as removed if it is a transition 5835 // Replaced descriptor has been counted as removed if it is a transition
5967 // that will be replaced. Adjust count in this case. 5836 // that will be replaced. Adjust count in this case.
5968 ++new_size; 5837 ++new_size;
5969 } 5838 }
5970 5839
5971 DescriptorArray* new_descriptors; 5840 DescriptorArray* new_descriptors;
5972 { MaybeObject* maybe_result = Allocate(new_size); 5841 { MaybeObject* maybe_result = Allocate(new_size, remove_transitions
5842 ? MAY_BE_SHARED
5843 : CANNOT_BE_SHARED);
danno 2012/06/06 09:25:12 nit: strange formatting. Put the *_SHARED value in
5973 if (!maybe_result->To(&new_descriptors)) return maybe_result; 5844 if (!maybe_result->To(&new_descriptors)) return maybe_result;
5974 } 5845 }
5975 5846
5976 DescriptorArray::WhitenessWitness witness(new_descriptors); 5847 DescriptorArray::WhitenessWitness witness(new_descriptors);
5977 5848
5978 // Set the enumeration index in the descriptors and set the enumeration index 5849 // Set the enumeration index in the descriptors and set the enumeration index
5979 // in the result. 5850 // in the result.
5980 int enumeration_index = NextEnumerationIndex(); 5851 int enumeration_index = NextEnumerationIndex();
5981 if (!descriptor->ContainsTransition()) { 5852 if (!descriptor->ContainsTransition()) {
5982 if (keep_enumeration_index) { 5853 if (keep_enumeration_index) {
5983 descriptor->SetEnumerationIndex(GetDetails(index).index()); 5854 descriptor->SetEnumerationIndex(GetDetails(index).index());
5984 } else { 5855 } else {
5985 descriptor->SetEnumerationIndex(enumeration_index); 5856 descriptor->SetEnumerationIndex(enumeration_index);
5986 ++enumeration_index; 5857 ++enumeration_index;
5987 } 5858 }
5988 } 5859 }
5860 Map* old_elements_transition = elements_transition_map();
5861 if ((!remove_transitions) && (old_elements_transition != NULL)) {
5862 new_descriptors->set_elements_transition_map(old_elements_transition);
5863 }
5989 new_descriptors->SetNextEnumerationIndex(enumeration_index); 5864 new_descriptors->SetNextEnumerationIndex(enumeration_index);
5990 5865
5991 // Copy the descriptors, filtering out transitions and null descriptors, 5866 // Copy the descriptors, filtering out transitions and null descriptors,
5992 // and inserting or replacing a descriptor. 5867 // and inserting or replacing a descriptor.
5993 int to_index = 0; 5868 int to_index = 0;
5994 int insertion_index = -1; 5869 int insertion_index = -1;
5995 int from_index = 0; 5870 int from_index = 0;
5996 while (from_index < number_of_descriptors()) { 5871 while (from_index < number_of_descriptors()) {
5997 if (insertion_index < 0 && 5872 if (insertion_index < 0 &&
5998 InsertionPointFound(GetKey(from_index), descriptor->GetKey())) { 5873 InsertionPointFound(GetKey(from_index), descriptor->GetKey())) {
5999 insertion_index = to_index++; 5874 insertion_index = to_index++;
6000 if (replacing) from_index++; 5875 if (replacing) from_index++;
6001 } else { 5876 } else {
6002 if (!(IsNullDescriptor(from_index) || 5877 if (!(IsNullDescriptor(from_index) ||
6003 (remove_transitions && IsTransitionOnly(from_index)))) { 5878 (remove_transitions && IsTransitionOnly(from_index)))) {
6004 MaybeObject* copy_result = 5879 MaybeObject* copy_result =
6005 new_descriptors->CopyFrom(to_index++, this, from_index, witness); 5880 new_descriptors->CopyFrom(to_index++, this, from_index, witness);
6006 if (copy_result->IsFailure()) return copy_result; 5881 if (copy_result->IsFailure()) return copy_result;
6007 } 5882 }
6008 from_index++; 5883 from_index++;
6009 } 5884 }
6010 } 5885 }
6011 if (insertion_index < 0) insertion_index = to_index++; 5886 if (insertion_index < 0) insertion_index = to_index++;
5887
5888 ASSERT(insertion_index < new_descriptors->number_of_descriptors());
6012 new_descriptors->Set(insertion_index, descriptor, witness); 5889 new_descriptors->Set(insertion_index, descriptor, witness);
6013 5890
6014 ASSERT(to_index == new_descriptors->number_of_descriptors()); 5891 ASSERT(to_index == new_descriptors->number_of_descriptors());
6015 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); 5892 SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
6016 5893
6017 return new_descriptors; 5894 return new_descriptors;
6018 } 5895 }
6019 5896
6020 5897
6021 MaybeObject* DescriptorArray::RemoveTransitions() { 5898 MaybeObject* DescriptorArray::RemoveTransitions(SharedMode shared_mode) {
6022 // Allocate the new descriptor array. 5899 // Allocate the new descriptor array.
6023 int new_number_of_descriptors = 0; 5900 int new_number_of_descriptors = 0;
6024 for (int i = 0; i < number_of_descriptors(); i++) { 5901 for (int i = 0; i < number_of_descriptors(); i++) {
6025 if (IsProperty(i)) new_number_of_descriptors++; 5902 if (IsProperty(i)) new_number_of_descriptors++;
6026 } 5903 }
6027 DescriptorArray* new_descriptors; 5904 DescriptorArray* new_descriptors;
6028 { MaybeObject* maybe_result = Allocate(new_number_of_descriptors); 5905 { MaybeObject* maybe_result = Allocate(new_number_of_descriptors,
5906 shared_mode);
6029 if (!maybe_result->To(&new_descriptors)) return maybe_result; 5907 if (!maybe_result->To(&new_descriptors)) return maybe_result;
6030 } 5908 }
6031 5909
6032 // Copy the content. 5910 // Copy the content.
6033 DescriptorArray::WhitenessWitness witness(new_descriptors); 5911 DescriptorArray::WhitenessWitness witness(new_descriptors);
6034 int next_descriptor = 0; 5912 int next_descriptor = 0;
6035 for (int i = 0; i < number_of_descriptors(); i++) { 5913 for (int i = 0; i < number_of_descriptors(); i++) {
6036 if (IsProperty(i)) { 5914 if (IsProperty(i)) {
6037 MaybeObject* copy_result = 5915 MaybeObject* copy_result =
6038 new_descriptors->CopyFrom(next_descriptor++, this, i, witness); 5916 new_descriptors->CopyFrom(next_descriptor++, this, i, witness);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
6102 5980
6103 5981
6104 void DescriptorArray::Sort(const WhitenessWitness& witness) { 5982 void DescriptorArray::Sort(const WhitenessWitness& witness) {
6105 SortUnchecked(witness); 5983 SortUnchecked(witness);
6106 SLOW_ASSERT(IsSortedNoDuplicates()); 5984 SLOW_ASSERT(IsSortedNoDuplicates());
6107 } 5985 }
6108 5986
6109 5987
6110 int DescriptorArray::BinarySearch(String* name, int low, int high) { 5988 int DescriptorArray::BinarySearch(String* name, int low, int high) {
6111 uint32_t hash = name->Hash(); 5989 uint32_t hash = name->Hash();
5990 int limit = high;
6112 5991
6113 while (low <= high) { 5992 ASSERT(low <= high);
5993
5994 while (low != high) {
6114 int mid = (low + high) / 2; 5995 int mid = (low + high) / 2;
6115 String* mid_name = GetKey(mid); 5996 String* mid_name = GetKey(mid);
6116 uint32_t mid_hash = mid_name->Hash(); 5997 uint32_t mid_hash = mid_name->Hash();
6117 5998
6118 if (mid_hash > hash) { 5999 if (mid_hash >= hash) {
6119 high = mid - 1; 6000 high = mid;
6120 continue; 6001 } else {
6002 low = mid + 1;
6121 } 6003 }
6122 if (mid_hash < hash) {
6123 low = mid + 1;
6124 continue;
6125 }
6126 // Found an element with the same hash-code.
6127 ASSERT(hash == mid_hash);
6128 // There might be more, so we find the first one and
6129 // check them all to see if we have a match.
6130 if (name == mid_name && !IsNullDescriptor(mid)) return mid;
6131 while ((mid > low) && (GetKey(mid - 1)->Hash() == hash)) mid--;
6132 for (; (mid <= high) && (GetKey(mid)->Hash() == hash); mid++) {
6133 if (GetKey(mid)->Equals(name) && !IsNullDescriptor(mid)) return mid;
6134 }
6135 break;
6136 } 6004 }
6005
6006 for (; low <= limit && GetKey(low)->Hash() == hash; ++low) {
6007 if (GetKey(low)->Equals(name) && !IsNullDescriptor(low))
6008 return low;
6009 }
6010
6137 return kNotFound; 6011 return kNotFound;
6138 } 6012 }
6139 6013
6140 6014
6141 int DescriptorArray::LinearSearch(String* name, int len) { 6015 int DescriptorArray::LinearSearch(SearchMode mode, String* name, int len) {
6142 uint32_t hash = name->Hash(); 6016 uint32_t hash = name->Hash();
6143 for (int number = 0; number < len; number++) { 6017 for (int number = 0; number < len; number++) {
6144 String* entry = GetKey(number); 6018 String* entry = GetKey(number);
6145 if ((entry->Hash() == hash) && 6019 if (mode == EXPECT_SORTED && entry->Hash() > hash) break;
6146 name->Equals(entry) && 6020 if (name->Equals(entry) && !IsNullDescriptor(number)) {
6147 !IsNullDescriptor(number)) {
6148 return number; 6021 return number;
6149 } 6022 }
6150 } 6023 }
6151 return kNotFound; 6024 return kNotFound;
6152 } 6025 }
6153 6026
6154 6027
6155 MaybeObject* AccessorPair::CopyWithoutTransitions() { 6028 MaybeObject* AccessorPair::CopyWithoutTransitions() {
6156 Heap* heap = GetHeap(); 6029 Heap* heap = GetHeap();
6157 AccessorPair* copy; 6030 AccessorPair* copy;
(...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after
7421 // live. If not, null the descriptor. Also drop the back pointer for that 7294 // live. If not, null the descriptor. Also drop the back pointer for that
7422 // map transition, so that this map is not reached again by following a back 7295 // map transition, so that this map is not reached again by following a back
7423 // pointer from that non-live map. 7296 // pointer from that non-live map.
7424 bool keep_entry = false; 7297 bool keep_entry = false;
7425 PropertyDetails details(d->GetDetails(i)); 7298 PropertyDetails details(d->GetDetails(i));
7426 switch (details.type()) { 7299 switch (details.type()) {
7427 case MAP_TRANSITION: 7300 case MAP_TRANSITION:
7428 case CONSTANT_TRANSITION: 7301 case CONSTANT_TRANSITION:
7429 ClearBackPointer(heap, d->GetValue(i), &keep_entry); 7302 ClearBackPointer(heap, d->GetValue(i), &keep_entry);
7430 break; 7303 break;
7431 case ELEMENTS_TRANSITION: {
7432 Object* object = d->GetValue(i);
7433 if (object->IsMap()) {
7434 ClearBackPointer(heap, object, &keep_entry);
7435 } else {
7436 FixedArray* array = FixedArray::cast(object);
7437 for (int j = 0; j < array->length(); ++j) {
7438 if (ClearBackPointer(heap, array->get(j), &keep_entry)) {
7439 array->set_undefined(j);
7440 }
7441 }
7442 }
7443 break;
7444 }
7445 case CALLBACKS: { 7304 case CALLBACKS: {
7446 Object* object = d->GetValue(i); 7305 Object* object = d->GetValue(i);
7447 if (object->IsAccessorPair()) { 7306 if (object->IsAccessorPair()) {
7448 AccessorPair* accessors = AccessorPair::cast(object); 7307 AccessorPair* accessors = AccessorPair::cast(object);
7449 if (ClearBackPointer(heap, accessors->getter(), &keep_entry)) { 7308 if (ClearBackPointer(heap, accessors->getter(), &keep_entry)) {
7450 accessors->set_getter(heap->the_hole_value()); 7309 accessors->set_getter(heap->the_hole_value());
7451 } 7310 }
7452 if (ClearBackPointer(heap, accessors->setter(), &keep_entry)) { 7311 if (ClearBackPointer(heap, accessors->setter(), &keep_entry)) {
7453 accessors->set_setter(heap->the_hole_value()); 7312 accessors->set_setter(heap->the_hole_value());
7454 } 7313 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
7594 } 7453 }
7595 7454
7596 7455
7597 MaybeObject* JSFunction::SetInstancePrototype(Object* value) { 7456 MaybeObject* JSFunction::SetInstancePrototype(Object* value) {
7598 ASSERT(value->IsJSReceiver()); 7457 ASSERT(value->IsJSReceiver());
7599 Heap* heap = GetHeap(); 7458 Heap* heap = GetHeap();
7600 if (has_initial_map()) { 7459 if (has_initial_map()) {
7601 // If the function has allocated the initial map 7460 // If the function has allocated the initial map
7602 // replace it with a copy containing the new prototype. 7461 // replace it with a copy containing the new prototype.
7603 Map* new_map; 7462 Map* new_map;
7604 MaybeObject* maybe_new_map = initial_map()->CopyDropTransitions(); 7463 MaybeObject* maybe_new_map =
7464 initial_map()->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
7605 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 7465 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
7606 new_map->set_prototype(value); 7466 new_map->set_prototype(value);
7607 MaybeObject* maybe_object = 7467 MaybeObject* maybe_object =
7608 set_initial_map_and_cache_transitions(new_map); 7468 set_initial_map_and_cache_transitions(new_map);
7609 if (maybe_object->IsFailure()) return maybe_object; 7469 if (maybe_object->IsFailure()) return maybe_object;
7610 } else { 7470 } else {
7611 // Put the value in the initial map field until an initial map is 7471 // Put the value in the initial map field until an initial map is
7612 // needed. At that point, a new initial map is created and the 7472 // needed. At that point, a new initial map is created and the
7613 // prototype is put into the initial map where it belongs. 7473 // prototype is put into the initial map where it belongs.
7614 set_prototype_or_initial_map(value); 7474 set_prototype_or_initial_map(value);
7615 } 7475 }
7616 heap->ClearInstanceofCache(); 7476 heap->ClearInstanceofCache();
7617 return value; 7477 return value;
7618 } 7478 }
7619 7479
7620 7480
7621 MaybeObject* JSFunction::SetPrototype(Object* value) { 7481 MaybeObject* JSFunction::SetPrototype(Object* value) {
7622 ASSERT(should_have_prototype()); 7482 ASSERT(should_have_prototype());
7623 Object* construct_prototype = value; 7483 Object* construct_prototype = value;
7624 7484
7625 // If the value is not a JSReceiver, store the value in the map's 7485 // If the value is not a JSReceiver, store the value in the map's
7626 // constructor field so it can be accessed. Also, set the prototype 7486 // constructor field so it can be accessed. Also, set the prototype
7627 // used for constructing objects to the original object prototype. 7487 // used for constructing objects to the original object prototype.
7628 // See ECMA-262 13.2.2. 7488 // See ECMA-262 13.2.2.
7629 if (!value->IsJSReceiver()) { 7489 if (!value->IsJSReceiver()) {
7630 // Copy the map so this does not affect unrelated functions. 7490 // Copy the map so this does not affect unrelated functions.
7631 // Remove map transitions because they point to maps with a 7491 // Remove map transitions because they point to maps with a
7632 // different prototype. 7492 // different prototype.
7633 Map* new_map; 7493 Map* new_map;
7634 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); 7494 { MaybeObject* maybe_new_map =
7495 map()->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
7635 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 7496 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
7636 } 7497 }
7637 Heap* heap = new_map->GetHeap(); 7498 Heap* heap = new_map->GetHeap();
7638 set_map(new_map); 7499 set_map(new_map);
7639 new_map->set_constructor(value); 7500 new_map->set_constructor(value);
7640 new_map->set_non_instance_prototype(true); 7501 new_map->set_non_instance_prototype(true);
7641 construct_prototype = 7502 construct_prototype =
7642 heap->isolate()->context()->global_context()-> 7503 heap->isolate()->context()->global_context()->
7643 initial_object_prototype(); 7504 initial_object_prototype();
7644 } else { 7505 } else {
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after
8491 8352
8492 const char* Code::PropertyType2String(PropertyType type) { 8353 const char* Code::PropertyType2String(PropertyType type) {
8493 switch (type) { 8354 switch (type) {
8494 case NORMAL: return "NORMAL"; 8355 case NORMAL: return "NORMAL";
8495 case FIELD: return "FIELD"; 8356 case FIELD: return "FIELD";
8496 case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION"; 8357 case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION";
8497 case CALLBACKS: return "CALLBACKS"; 8358 case CALLBACKS: return "CALLBACKS";
8498 case HANDLER: return "HANDLER"; 8359 case HANDLER: return "HANDLER";
8499 case INTERCEPTOR: return "INTERCEPTOR"; 8360 case INTERCEPTOR: return "INTERCEPTOR";
8500 case MAP_TRANSITION: return "MAP_TRANSITION"; 8361 case MAP_TRANSITION: return "MAP_TRANSITION";
8501 case ELEMENTS_TRANSITION: return "ELEMENTS_TRANSITION";
8502 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; 8362 case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION";
8503 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; 8363 case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR";
8504 } 8364 }
8505 UNREACHABLE(); // keep the compiler happy 8365 UNREACHABLE(); // keep the compiler happy
8506 return NULL; 8366 return NULL;
8507 } 8367 }
8508 8368
8509 8369
8510 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { 8370 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) {
8511 const char* name = NULL; 8371 const char* name = NULL;
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
8882 } 8742 }
8883 8743
8884 // Set the new prototype of the object. 8744 // Set the new prototype of the object.
8885 Map* map = real_receiver->map(); 8745 Map* map = real_receiver->map();
8886 8746
8887 // Nothing to do if prototype is already set. 8747 // Nothing to do if prototype is already set.
8888 if (map->prototype() == value) return value; 8748 if (map->prototype() == value) return value;
8889 8749
8890 Object* new_map = map->GetPrototypeTransition(value); 8750 Object* new_map = map->GetPrototypeTransition(value);
8891 if (new_map == NULL) { 8751 if (new_map == NULL) {
8892 { MaybeObject* maybe_new_map = map->CopyDropTransitions(); 8752 { MaybeObject* maybe_new_map =
8753 map->CopyDropTransitions(DescriptorArray::MAY_BE_SHARED);
8893 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 8754 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
8894 } 8755 }
8895 8756
8896 { MaybeObject* maybe_new_cache = 8757 { MaybeObject* maybe_new_cache =
8897 map->PutPrototypeTransition(value, Map::cast(new_map)); 8758 map->PutPrototypeTransition(value, Map::cast(new_map));
8898 if (maybe_new_cache->IsFailure()) return maybe_new_cache; 8759 if (maybe_new_cache->IsFailure()) return maybe_new_cache;
8899 } 8760 }
8900 8761
8901 Map::cast(new_map)->set_prototype(value); 8762 Map::cast(new_map)->set_prototype(value);
8902 } 8763 }
(...skipping 2260 matching lines...) Expand 10 before | Expand all | Expand 10 after
11163 entry = NextProbe(entry, count++, capacity); 11024 entry = NextProbe(entry, count++, capacity);
11164 } 11025 }
11165 return kNotFound; 11026 return kNotFound;
11166 } 11027 }
11167 11028
11168 11029
11169 bool StringDictionary::ContainsTransition(int entry) { 11030 bool StringDictionary::ContainsTransition(int entry) {
11170 switch (DetailsAt(entry).type()) { 11031 switch (DetailsAt(entry).type()) {
11171 case MAP_TRANSITION: 11032 case MAP_TRANSITION:
11172 case CONSTANT_TRANSITION: 11033 case CONSTANT_TRANSITION:
11173 case ELEMENTS_TRANSITION:
11174 return true; 11034 return true;
11175 case CALLBACKS: { 11035 case CALLBACKS: {
11176 Object* value = ValueAt(entry); 11036 Object* value = ValueAt(entry);
11177 if (!value->IsAccessorPair()) return false; 11037 if (!value->IsAccessorPair()) return false;
11178 AccessorPair* accessors = AccessorPair::cast(value); 11038 AccessorPair* accessors = AccessorPair::cast(value);
11179 return accessors->getter()->IsMap() || accessors->setter()->IsMap(); 11039 return accessors->getter()->IsMap() || accessors->setter()->IsMap();
11180 } 11040 }
11181 case NORMAL: 11041 case NORMAL:
11182 case FIELD: 11042 case FIELD:
11183 case CONSTANT_FUNCTION: 11043 case CONSTANT_FUNCTION:
(...skipping 1429 matching lines...) Expand 10 before | Expand all | Expand 10 after
12613 if (type == NORMAL && 12473 if (type == NORMAL &&
12614 (!value->IsJSFunction() || heap->InNewSpace(value))) { 12474 (!value->IsJSFunction() || heap->InNewSpace(value))) {
12615 number_of_fields += 1; 12475 number_of_fields += 1;
12616 } 12476 }
12617 } 12477 }
12618 } 12478 }
12619 12479
12620 // Allocate the instance descriptor. 12480 // Allocate the instance descriptor.
12621 DescriptorArray* descriptors; 12481 DescriptorArray* descriptors;
12622 { MaybeObject* maybe_descriptors = 12482 { MaybeObject* maybe_descriptors =
12623 DescriptorArray::Allocate(instance_descriptor_length); 12483 DescriptorArray::Allocate(instance_descriptor_length,
12484 DescriptorArray::MAY_BE_SHARED);
12624 if (!maybe_descriptors->To<DescriptorArray>(&descriptors)) { 12485 if (!maybe_descriptors->To<DescriptorArray>(&descriptors)) {
12625 return maybe_descriptors; 12486 return maybe_descriptors;
12626 } 12487 }
12627 } 12488 }
12628 12489
12629 DescriptorArray::WhitenessWitness witness(descriptors); 12490 DescriptorArray::WhitenessWitness witness(descriptors);
12630 12491
12631 int inobject_props = obj->map()->inobject_properties(); 12492 int inobject_props = obj->map()->inobject_properties();
12632 int number_of_allocated_fields = 12493 int number_of_allocated_fields =
12633 number_of_fields + unused_property_fields - inobject_props; 12494 number_of_fields + unused_property_fields - inobject_props;
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
13217 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13078 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13218 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13079 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13219 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13080 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13220 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13081 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13221 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13082 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13222 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13083 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13223 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13084 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13224 } 13085 }
13225 13086
13226 } } // namespace v8::internal 13087 } } // namespace v8::internal
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698