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

Side by Side Diff: src/objects.cc

Issue 10170030: Implement tracking and optimizations of packed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: ia32 ready to go Created 8 years, 7 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 #include "vm-state-inl.h" 49 #include "vm-state-inl.h"
50 50
51 #ifdef ENABLE_DISASSEMBLER 51 #ifdef ENABLE_DISASSEMBLER
52 #include "disasm.h" 52 #include "disasm.h"
53 #include "disassembler.h" 53 #include "disassembler.h"
54 #endif 54 #endif
55 55
56 namespace v8 { 56 namespace v8 {
57 namespace internal { 57 namespace internal {
58 58
59 void PrintElementsKind(FILE* out, ElementsKind kind) {
60 ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
61 PrintF(out, "%s", accessor->name());
62 }
63
64 59
65 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, 60 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
66 Object* value) { 61 Object* value) {
67 Object* result; 62 Object* result;
68 { MaybeObject* maybe_result = 63 { MaybeObject* maybe_result =
69 constructor->GetHeap()->AllocateJSObject(constructor); 64 constructor->GetHeap()->AllocateJSObject(constructor);
70 if (!maybe_result->ToObject(&result)) return maybe_result; 65 if (!maybe_result->ToObject(&result)) return maybe_result;
71 } 66 }
72 JSValue::cast(result)->set_value(value); 67 JSValue::cast(result)->set_value(value);
73 return result; 68 return result;
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 bool JSObject::IsDirty() { 531 bool JSObject::IsDirty() {
537 Object* cons_obj = map()->constructor(); 532 Object* cons_obj = map()->constructor();
538 if (!cons_obj->IsJSFunction()) 533 if (!cons_obj->IsJSFunction())
539 return true; 534 return true;
540 JSFunction* fun = JSFunction::cast(cons_obj); 535 JSFunction* fun = JSFunction::cast(cons_obj);
541 if (!fun->shared()->IsApiFunction()) 536 if (!fun->shared()->IsApiFunction())
542 return true; 537 return true;
543 // If the object is fully fast case and has the same map it was 538 // If the object is fully fast case and has the same map it was
544 // created with then no changes can have been made to it. 539 // created with then no changes can have been made to it.
545 return map() != fun->initial_map() 540 return map() != fun->initial_map()
546 || !HasFastElements() 541 || !HasFastObjectElements()
547 || !HasFastProperties(); 542 || !HasFastProperties();
548 } 543 }
549 544
550 545
551 Handle<Object> Object::GetProperty(Handle<Object> object, 546 Handle<Object> Object::GetProperty(Handle<Object> object,
552 Handle<Object> receiver, 547 Handle<Object> receiver,
553 LookupResult* result, 548 LookupResult* result,
554 Handle<String> key, 549 Handle<String> key,
555 PropertyAttributes* attributes) { 550 PropertyAttributes* attributes) {
556 Isolate* isolate = object->IsHeapObject() 551 Isolate* isolate = object->IsHeapObject()
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 cs->set_second(heap->empty_string(), SKIP_WRITE_BARRIER); 890 cs->set_second(heap->empty_string(), SKIP_WRITE_BARRIER);
896 return result; 891 return result;
897 } 892 }
898 default: 893 default:
899 return this; 894 return this;
900 } 895 }
901 } 896 }
902 897
903 898
904 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { 899 bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
905 // Externalizing twice leaks the external resource, so it's 900 // Externalizing twice leaks the external resource, so its prohibited by the
Jakob Kummerow 2012/05/13 21:55:27 Why this change? Original version was correct.
danno 2012/05/22 11:05:21 Done.
906 // prohibited by the API. 901 // API.
907 ASSERT(!this->IsExternalString()); 902 ASSERT(!this->IsExternalString());
908 #ifdef DEBUG 903 #ifdef DEBUG
909 if (FLAG_enable_slow_asserts) { 904 if (FLAG_enable_slow_asserts) {
910 // Assert that the resource and the string are equivalent. 905 // Assert that the resource and the string are equivalent.
911 ASSERT(static_cast<size_t>(this->length()) == resource->length()); 906 ASSERT(static_cast<size_t>(this->length()) == resource->length());
912 ScopedVector<uc16> smart_chars(this->length()); 907 ScopedVector<uc16> smart_chars(this->length());
913 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); 908 String::WriteToFlat(this, smart_chars.start(), 0, this->length());
914 ASSERT(memcmp(smart_chars.start(), 909 ASSERT(memcmp(smart_chars.start(),
915 resource->data(), 910 resource->data(),
916 resource->length() * sizeof(smart_chars[0])) == 0); 911 resource->length() * sizeof(smart_chars[0])) == 0);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 } 1055 }
1061 accumulator->Put('>'); 1056 accumulator->Put('>');
1062 } 1057 }
1063 return; 1058 return;
1064 } 1059 }
1065 1060
1066 1061
1067 void JSObject::JSObjectShortPrint(StringStream* accumulator) { 1062 void JSObject::JSObjectShortPrint(StringStream* accumulator) {
1068 switch (map()->instance_type()) { 1063 switch (map()->instance_type()) {
1069 case JS_ARRAY_TYPE: { 1064 case JS_ARRAY_TYPE: {
1070 double length = JSArray::cast(this)->length()->Number(); 1065 double length = JSArray::cast(this)->length()->IsUndefined()
1066 ? 0 :
Jakob Kummerow 2012/05/13 21:55:27 nit: I'd put the colon on the next line, directly
danno 2012/05/22 11:05:21 Done.
1067 JSArray::cast(this)->length()->Number();
1071 accumulator->Add("<JS Array[%u]>", static_cast<uint32_t>(length)); 1068 accumulator->Add("<JS Array[%u]>", static_cast<uint32_t>(length));
1072 break; 1069 break;
1073 } 1070 }
1074 case JS_WEAK_MAP_TYPE: { 1071 case JS_WEAK_MAP_TYPE: {
1075 accumulator->Add("<JS WeakMap>"); 1072 accumulator->Add("<JS WeakMap>");
1076 break; 1073 break;
1077 } 1074 }
1078 case JS_REGEXP_TYPE: { 1075 case JS_REGEXP_TYPE: {
1079 accumulator->Add("<JS RegExp>"); 1076 accumulator->Add("<JS RegExp>");
1080 break; 1077 break;
(...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2192 2189
2193 2190
2194 template <class T> 2191 template <class T>
2195 static Handle<T> MaybeNull(T* p) { 2192 static Handle<T> MaybeNull(T* p) {
2196 if (p == NULL) return Handle<T>::null(); 2193 if (p == NULL) return Handle<T>::null();
2197 return Handle<T>(p); 2194 return Handle<T>(p);
2198 } 2195 }
2199 2196
2200 2197
2201 Handle<Map> Map::FindTransitionedMap(MapHandleList* candidates) { 2198 Handle<Map> Map::FindTransitionedMap(MapHandleList* candidates) {
2202 ElementsKind elms_kind = elements_kind(); 2199 ElementsKind kind = elements_kind();
2203 if (elms_kind == FAST_DOUBLE_ELEMENTS) { 2200 Handle<Map> transitioned_map = Handle<Map>::null();
2204 bool dummy = true; 2201 Handle<Map> current_map(this);
2205 Handle<Map> fast_map = 2202 bool packed = IsFastPackedElementsKind(kind);
2206 MaybeNull(LookupElementsTransitionMap(FAST_ELEMENTS, &dummy)); 2203 if (IsTransitionableFastElementsKind(kind)) {
2207 if (!fast_map.is_null() && ContainsMap(candidates, fast_map)) { 2204 while (CanTransitionToMoreGeneralFastElementsKind(kind, false)) {
2208 return fast_map; 2205 kind = GetNextMoreGeneralFastElementsKind(kind, false);
2206 bool dummy = true;
2207 Handle<Map> maybe_transitioned_map =
2208 MaybeNull(current_map->LookupElementsTransitionMap(kind, &dummy));
2209 if (maybe_transitioned_map.is_null()) break;
2210 if (ContainsMap(candidates, maybe_transitioned_map) &&
2211 (packed || !IsFastPackedElementsKind(kind))) {
2212 transitioned_map = maybe_transitioned_map;
2213 if (!IsFastPackedElementsKind(kind)) packed = false;
2214 }
2215 current_map = maybe_transitioned_map;
2209 } 2216 }
2210 return Handle<Map>::null();
2211 } 2217 }
2212 if (elms_kind == FAST_SMI_ONLY_ELEMENTS) { 2218 return transitioned_map;
2213 bool dummy = true;
2214 Handle<Map> double_map =
2215 MaybeNull(LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, &dummy));
2216 // In the current implementation, if the DOUBLE map doesn't exist, the
2217 // FAST map can't exist either.
2218 if (double_map.is_null()) return Handle<Map>::null();
2219 Handle<Map> fast_map =
2220 MaybeNull(double_map->LookupElementsTransitionMap(FAST_ELEMENTS,
2221 &dummy));
2222 if (!fast_map.is_null() && ContainsMap(candidates, fast_map)) {
2223 return fast_map;
2224 }
2225 if (ContainsMap(candidates, double_map)) return double_map;
2226 }
2227 return Handle<Map>::null();
2228 } 2219 }
2229 2220
2221
2230 static Map* GetElementsTransitionMapFromDescriptor(Object* descriptor_contents, 2222 static Map* GetElementsTransitionMapFromDescriptor(Object* descriptor_contents,
2231 ElementsKind elements_kind) { 2223 ElementsKind elements_kind) {
2232 if (descriptor_contents->IsMap()) { 2224 if (descriptor_contents->IsMap()) {
2233 Map* map = Map::cast(descriptor_contents); 2225 Map* map = Map::cast(descriptor_contents);
2234 if (map->elements_kind() == elements_kind) { 2226 if (map->elements_kind() == elements_kind) {
2235 return map; 2227 return map;
2236 } 2228 }
2237 return NULL; 2229 return NULL;
2238 } 2230 }
2239 2231
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2328 } else { 2320 } else {
2329 if (safe_to_add_transition != NULL) { 2321 if (safe_to_add_transition != NULL) {
2330 *safe_to_add_transition = false; 2322 *safe_to_add_transition = false;
2331 } 2323 }
2332 } 2324 }
2333 } 2325 }
2334 return NULL; 2326 return NULL;
2335 } 2327 }
2336 2328
2337 2329
2338 Map* Map::LookupElementsTransitionMap(ElementsKind elements_kind, 2330 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind,
2339 bool* safe_to_add_transition) { 2331 bool* safe_to_add_transition) {
2340 // Special case: indirect SMI->FAST transition (cf. comment in 2332 ElementsKind from_kind = elements_kind();
2341 // AddElementsTransition()). 2333 if (IsFastElementsKind(from_kind) && IsFastElementsKind(to_kind)) {
2342 if (this->elements_kind() == FAST_SMI_ONLY_ELEMENTS && 2334 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
2343 elements_kind == FAST_ELEMENTS) { 2335 if (safe_to_add_transition) *safe_to_add_transition = false;
2344 Map* double_map = this->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, 2336 return NULL;
2345 safe_to_add_transition); 2337 }
2346 if (double_map == NULL) return double_map; 2338 ElementsKind transitioned_from_kind =
2347 return double_map->LookupElementsTransitionMap(FAST_ELEMENTS, 2339 GetNextMoreGeneralFastElementsKind(from_kind, false);
2340
2341
2342 // If the transition is a single step in the transition sequence, fall
2343 // through to looking it up and returning it. If it requires several steps,
2344 // divide and conquer.
2345 if (transitioned_from_kind != to_kind) {
2346 // If the transition is several steps in the lattice, divide and conquer.
2347 Map* from_map = LookupElementsTransitionMap(transitioned_from_kind,
2348 safe_to_add_transition);
2349 if (from_map == NULL) return NULL;
2350 return from_map->LookupElementsTransitionMap(to_kind,
2348 safe_to_add_transition); 2351 safe_to_add_transition);
2352 }
2349 } 2353 }
2350 Object* descriptor_contents = GetDescriptorContents( 2354 Object* descriptor_contents = GetDescriptorContents(
2351 elements_transition_sentinel_name(), safe_to_add_transition); 2355 elements_transition_sentinel_name(), safe_to_add_transition);
2352 if (descriptor_contents != NULL) { 2356 if (descriptor_contents != NULL) {
2353 Map* maybe_transition_map = 2357 Map* maybe_transition_map =
2354 GetElementsTransitionMapFromDescriptor(descriptor_contents, 2358 GetElementsTransitionMapFromDescriptor(descriptor_contents,
2355 elements_kind); 2359 to_kind);
2356 ASSERT(maybe_transition_map == NULL || maybe_transition_map->IsMap()); 2360 ASSERT(maybe_transition_map == NULL || maybe_transition_map->IsMap());
2357 return maybe_transition_map; 2361 return maybe_transition_map;
2358 } 2362 }
2359 return NULL; 2363 return NULL;
2360 } 2364 }
2361 2365
2362 2366
2363 MaybeObject* Map::AddElementsTransition(ElementsKind elements_kind, 2367 MaybeObject* Map::AddElementsTransition(ElementsKind to_kind,
2364 Map* transitioned_map) { 2368 Map* transitioned_map) {
2365 // The map transition graph should be a tree, therefore the transition 2369 ElementsKind from_kind = elements_kind();
2366 // from SMI to FAST elements is not done directly, but by going through 2370 if (IsFastElementsKind(from_kind) && IsFastElementsKind(to_kind)) {
2367 // DOUBLE elements first. 2371 ASSERT(IsMoreGeneralElementsKindTransition(from_kind, to_kind));
2368 if (this->elements_kind() == FAST_SMI_ONLY_ELEMENTS && 2372 ElementsKind transitioned_from_kind =
2369 elements_kind == FAST_ELEMENTS) { 2373 GetNextMoreGeneralFastElementsKind(from_kind, false);
2370 bool safe_to_add = true; 2374 // The map transitions graph should be a tree, therefore transitions to
2371 Map* double_map = this->LookupElementsTransitionMap( 2375 // ElementsKind that are not adjacent in the ElementsKind sequence are not
2372 FAST_DOUBLE_ELEMENTS, &safe_to_add); 2376 // done directly, but instead by going through intermediate ElementsKinds
2373 // This method is only called when safe_to_add_transition has been found 2377 // first.
2374 // to be true earlier. 2378 if (to_kind != transitioned_from_kind) {
2375 ASSERT(safe_to_add); 2379 bool safe_to_add = true;
2380 Map* intermediate_map = LookupElementsTransitionMap(
2381 transitioned_from_kind, &safe_to_add);
2382 // This method is only called when safe_to_add_transition has been found
Jakob Kummerow 2012/05/13 21:55:27 nit: s/safe_to_add_transition/safe_to_add/
danno 2012/05/22 11:05:21 Done.
2383 // to be true earlier.
2384 ASSERT(safe_to_add);
2376 2385
2377 if (double_map == NULL) { 2386 if (intermediate_map == NULL) {
2378 MaybeObject* maybe_map = this->CopyDropTransitions(); 2387 MaybeObject* maybe_map = CopyDropTransitions();
2379 if (!maybe_map->To(&double_map)) return maybe_map; 2388 if (!maybe_map->To(&intermediate_map)) return maybe_map;
2380 double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS); 2389 intermediate_map->set_elements_kind(transitioned_from_kind);
2381 MaybeObject* maybe_double_transition = this->AddElementsTransition( 2390 MaybeObject* maybe_transition = AddElementsTransition(
2382 FAST_DOUBLE_ELEMENTS, double_map); 2391 transitioned_from_kind, intermediate_map);
2383 if (maybe_double_transition->IsFailure()) return maybe_double_transition; 2392 if (maybe_transition->IsFailure()) return maybe_transition;
2393 }
2394 return intermediate_map->AddElementsTransition(to_kind, transitioned_map);
2384 } 2395 }
2385 return double_map->AddElementsTransition(FAST_ELEMENTS, transitioned_map);
2386 } 2396 }
2387 2397
2388 bool safe_to_add_transition = true; 2398 bool safe_to_add_transition = true;
2389 Object* descriptor_contents = GetDescriptorContents( 2399 Object* descriptor_contents = GetDescriptorContents(
2390 elements_transition_sentinel_name(), &safe_to_add_transition); 2400 elements_transition_sentinel_name(), &safe_to_add_transition);
2391 // This method is only called when safe_to_add_transition has been found 2401 // This method is only called when safe_to_add_transition has been found
2392 // to be true earlier. 2402 // to be true earlier.
2393 ASSERT(safe_to_add_transition); 2403 ASSERT(safe_to_add_transition);
2394 MaybeObject* maybe_new_contents = 2404 MaybeObject* maybe_new_contents =
2395 AddElementsTransitionMapToDescriptor(descriptor_contents, 2405 AddElementsTransitionMapToDescriptor(descriptor_contents,
(...skipping 30 matching lines...) Expand all
2426 ElementsKind from_kind = current_map->elements_kind(); 2436 ElementsKind from_kind = current_map->elements_kind();
2427 2437
2428 if (from_kind == to_kind) return current_map; 2438 if (from_kind == to_kind) return current_map;
2429 2439
2430 // Only objects with FastProperties can have DescriptorArrays and can track 2440 // Only objects with FastProperties can have DescriptorArrays and can track
2431 // element-related maps. Also don't add descriptors to maps that are shared. 2441 // element-related maps. Also don't add descriptors to maps that are shared.
2432 bool safe_to_add_transition = HasFastProperties() && 2442 bool safe_to_add_transition = HasFastProperties() &&
2433 !current_map->IsUndefined() && 2443 !current_map->IsUndefined() &&
2434 !current_map->is_shared(); 2444 !current_map->is_shared();
2435 2445
2436 // Prevent long chains of DICTIONARY -> FAST_ELEMENTS maps caused by objects 2446 // Prevent long chains of DICTIONARY -> FAST_*_ELEMENTS maps caused by objects
2437 // with elements that switch back and forth between dictionary and fast 2447 // with elements that switch back and forth between dictionary and fast
2438 // element mode. 2448 // element modes.
2439 if (from_kind == DICTIONARY_ELEMENTS && to_kind == FAST_ELEMENTS) { 2449 if (from_kind == DICTIONARY_ELEMENTS &&
2450 IsFastObjectElementsKind(to_kind)) {
Jakob Kummerow 2012/05/13 21:55:27 Wouldn't it make sense to check for any FAST kind
danno 2012/05/22 11:05:21 Done.
2440 safe_to_add_transition = false; 2451 safe_to_add_transition = false;
2441 } 2452 }
2442 2453
2443 if (safe_to_add_transition) { 2454 if (safe_to_add_transition) {
2444 // It's only safe to manipulate the descriptor array if it would be 2455 // It's only safe to manipulate the descriptor array if it would be
2445 // safe to add a transition. 2456 // safe to add a transition.
2446 Map* maybe_transition_map = current_map->LookupElementsTransitionMap( 2457 Map* maybe_transition_map = current_map->LookupElementsTransitionMap(
2447 to_kind, &safe_to_add_transition); 2458 to_kind, &safe_to_add_transition);
2448 if (maybe_transition_map != NULL) { 2459 if (maybe_transition_map != NULL) {
2449 return maybe_transition_map; 2460 return maybe_transition_map;
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after
3465 // Find the backing store. 3476 // Find the backing store.
3466 FixedArrayBase* array = FixedArrayBase::cast(elements()); 3477 FixedArrayBase* array = FixedArrayBase::cast(elements());
3467 Map* old_map = array->map(); 3478 Map* old_map = array->map();
3468 bool is_arguments = 3479 bool is_arguments =
3469 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); 3480 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map());
3470 if (is_arguments) { 3481 if (is_arguments) {
3471 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); 3482 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1));
3472 } 3483 }
3473 if (array->IsDictionary()) return array; 3484 if (array->IsDictionary()) return array;
3474 3485
3475 ASSERT(HasFastElements() || 3486 ASSERT(HasFastSmiOrObjectElements() ||
3476 HasFastSmiOnlyElements() ||
3477 HasFastDoubleElements() || 3487 HasFastDoubleElements() ||
3478 HasFastArgumentsElements()); 3488 HasFastArgumentsElements());
3479 // Compute the effective length and allocate a new backing store. 3489 // Compute the effective length and allocate a new backing store.
3480 int length = IsJSArray() 3490 int length = IsJSArray()
3481 ? Smi::cast(JSArray::cast(this)->length())->value() 3491 ? Smi::cast(JSArray::cast(this)->length())->value()
3482 : array->length(); 3492 : array->length();
3483 int old_capacity = 0; 3493 int old_capacity = 0;
3484 int used_elements = 0; 3494 int used_elements = 0;
3485 GetElementsCapacityAndUsage(&old_capacity, &used_elements); 3495 GetElementsCapacityAndUsage(&old_capacity, &used_elements);
3486 SeededNumberDictionary* dictionary = NULL; 3496 SeededNumberDictionary* dictionary = NULL;
(...skipping 14 matching lines...) Expand all
3501 } else { 3511 } else {
3502 // Objects must be allocated in the old object space, since the 3512 // Objects must be allocated in the old object space, since the
3503 // overall number of HeapNumbers needed for the conversion might 3513 // overall number of HeapNumbers needed for the conversion might
3504 // exceed the capacity of new space, and we would fail repeatedly 3514 // exceed the capacity of new space, and we would fail repeatedly
3505 // trying to convert the FixedDoubleArray. 3515 // trying to convert the FixedDoubleArray.
3506 MaybeObject* maybe_value_object = 3516 MaybeObject* maybe_value_object =
3507 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED); 3517 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED);
3508 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 3518 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
3509 } 3519 }
3510 } else { 3520 } else {
3511 ASSERT(old_map->has_fast_elements() || 3521 ASSERT(old_map->has_fast_smi_or_object_elements());
3512 old_map->has_fast_smi_only_elements());
3513 value = FixedArray::cast(array)->get(i); 3522 value = FixedArray::cast(array)->get(i);
3514 } 3523 }
3515 PropertyDetails details = PropertyDetails(NONE, NORMAL); 3524 PropertyDetails details = PropertyDetails(NONE, NORMAL);
3516 if (!value->IsTheHole()) { 3525 if (!value->IsTheHole()) {
3517 Object* result; 3526 Object* result;
3518 MaybeObject* maybe_result = 3527 MaybeObject* maybe_result =
3519 dictionary->AddNumberEntry(i, value, details); 3528 dictionary->AddNumberEntry(i, value, details);
3520 if (!maybe_result->ToObject(&result)) return maybe_result; 3529 if (!maybe_result->ToObject(&result)) return maybe_result;
3521 dictionary = SeededNumberDictionary::cast(result); 3530 dictionary = SeededNumberDictionary::cast(result);
3522 } 3531 }
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
3989 if (IsJSProxy()) { 3998 if (IsJSProxy()) {
3990 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode); 3999 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode);
3991 } 4000 }
3992 return JSObject::cast(this)->DeleteProperty(name, mode); 4001 return JSObject::cast(this)->DeleteProperty(name, mode);
3993 } 4002 }
3994 4003
3995 4004
3996 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, 4005 bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
3997 ElementsKind kind, 4006 ElementsKind kind,
3998 Object* object) { 4007 Object* object) {
3999 ASSERT(kind == FAST_ELEMENTS || 4008 ASSERT(IsFastObjectElementsKind(kind) ||
4000 kind == DICTIONARY_ELEMENTS); 4009 kind == DICTIONARY_ELEMENTS);
4001 if (kind == FAST_ELEMENTS) { 4010 if (IsFastObjectElementsKind(kind)) {
4002 int length = IsJSArray() 4011 int length = IsJSArray()
4003 ? Smi::cast(JSArray::cast(this)->length())->value() 4012 ? Smi::cast(JSArray::cast(this)->length())->value()
4004 : elements->length(); 4013 : elements->length();
4005 for (int i = 0; i < length; ++i) { 4014 for (int i = 0; i < length; ++i) {
4006 Object* element = elements->get(i); 4015 Object* element = elements->get(i);
4007 if (!element->IsTheHole() && element == object) return true; 4016 if (!element->IsTheHole() && element == object) return true;
4008 } 4017 }
4009 } else { 4018 } else {
4010 Object* key = 4019 Object* key =
4011 SeededNumberDictionary::cast(elements)->SlowReverseLookup(object); 4020 SeededNumberDictionary::cast(elements)->SlowReverseLookup(object);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4043 case EXTERNAL_PIXEL_ELEMENTS: 4052 case EXTERNAL_PIXEL_ELEMENTS:
4044 case EXTERNAL_BYTE_ELEMENTS: 4053 case EXTERNAL_BYTE_ELEMENTS:
4045 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4054 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4046 case EXTERNAL_SHORT_ELEMENTS: 4055 case EXTERNAL_SHORT_ELEMENTS:
4047 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4056 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
4048 case EXTERNAL_INT_ELEMENTS: 4057 case EXTERNAL_INT_ELEMENTS:
4049 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4058 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
4050 case EXTERNAL_FLOAT_ELEMENTS: 4059 case EXTERNAL_FLOAT_ELEMENTS:
4051 case EXTERNAL_DOUBLE_ELEMENTS: 4060 case EXTERNAL_DOUBLE_ELEMENTS:
4052 case FAST_DOUBLE_ELEMENTS: 4061 case FAST_DOUBLE_ELEMENTS:
4062 case FAST_HOLEY_DOUBLE_ELEMENTS:
4053 // Raw pixels and external arrays do not reference other 4063 // Raw pixels and external arrays do not reference other
4054 // objects. 4064 // objects.
4055 break; 4065 break;
4056 case FAST_SMI_ONLY_ELEMENTS: 4066 case FAST_SMI_ELEMENTS:
4067 case FAST_HOLEY_SMI_ELEMENTS:
4057 break; 4068 break;
4058 case FAST_ELEMENTS: 4069 case FAST_ELEMENTS:
4070 case FAST_HOLEY_ELEMENTS:
4059 case DICTIONARY_ELEMENTS: { 4071 case DICTIONARY_ELEMENTS: {
4060 FixedArray* elements = FixedArray::cast(this->elements()); 4072 FixedArray* elements = FixedArray::cast(this->elements());
4061 if (ReferencesObjectFromElements(elements, kind, obj)) return true; 4073 if (ReferencesObjectFromElements(elements, kind, obj)) return true;
4062 break; 4074 break;
4063 } 4075 }
4064 case NON_STRICT_ARGUMENTS_ELEMENTS: { 4076 case NON_STRICT_ARGUMENTS_ELEMENTS: {
4065 FixedArray* parameter_map = FixedArray::cast(elements()); 4077 FixedArray* parameter_map = FixedArray::cast(elements());
4066 // Check the mapped parameters. 4078 // Check the mapped parameters.
4067 int length = parameter_map->length(); 4079 int length = parameter_map->length();
4068 for (int i = 2; i < length; ++i) { 4080 for (int i = 2; i < length; ++i) {
4069 Object* value = parameter_map->get(i); 4081 Object* value = parameter_map->get(i);
4070 if (!value->IsTheHole() && value == obj) return true; 4082 if (!value->IsTheHole() && value == obj) return true;
4071 } 4083 }
4072 // Check the arguments. 4084 // Check the arguments.
4073 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 4085 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
4074 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : FAST_ELEMENTS; 4086 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS :
4087 FAST_HOLEY_ELEMENTS;
4075 if (ReferencesObjectFromElements(arguments, kind, obj)) return true; 4088 if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
4076 break; 4089 break;
4077 } 4090 }
4078 } 4091 }
4079 4092
4080 // For functions check the context. 4093 // For functions check the context.
4081 if (IsJSFunction()) { 4094 if (IsJSFunction()) {
4082 // Get the constructor function for arguments array. 4095 // Get the constructor function for arguments array.
4083 JSObject* arguments_boilerplate = 4096 JSObject* arguments_boilerplate =
4084 heap->isolate()->context()->global_context()-> 4097 heap->isolate()->context()->global_context()->
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
4298 for (Object* current = this; 4311 for (Object* current = this;
4299 current != heap->null_value(); 4312 current != heap->null_value();
4300 current = JSObject::cast(current)->GetPrototype()) { 4313 current = JSObject::cast(current)->GetPrototype()) {
4301 JSReceiver::cast(current)->LocalLookup(name, result); 4314 JSReceiver::cast(current)->LocalLookup(name, result);
4302 if (result->IsProperty()) return; 4315 if (result->IsProperty()) return;
4303 } 4316 }
4304 result->NotFound(); 4317 result->NotFound();
4305 } 4318 }
4306 4319
4307 4320
4308 // Search object and it's prototype chain for callback properties. 4321 // Search object and its prototype chain for callback properties.
4309 void JSObject::LookupCallback(String* name, LookupResult* result) { 4322 void JSObject::LookupCallback(String* name, LookupResult* result) {
4310 Heap* heap = GetHeap(); 4323 Heap* heap = GetHeap();
4311 for (Object* current = this; 4324 for (Object* current = this;
4312 current != heap->null_value() && current->IsJSObject(); 4325 current != heap->null_value() && current->IsJSObject();
4313 current = JSObject::cast(current)->GetPrototype()) { 4326 current = JSObject::cast(current)->GetPrototype()) {
4314 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); 4327 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
4315 if (result->IsFound() && result->type() == CALLBACKS) return; 4328 if (result->IsFound() && result->type() == CALLBACKS) return;
4316 } 4329 }
4317 result->NotFound(); 4330 result->NotFound();
4318 } 4331 }
(...skipping 23 matching lines...) Expand all
4342 } 4355 }
4343 return false; 4356 return false;
4344 } 4357 }
4345 4358
4346 4359
4347 MaybeObject* JSObject::DefineElementAccessor(uint32_t index, 4360 MaybeObject* JSObject::DefineElementAccessor(uint32_t index,
4348 Object* getter, 4361 Object* getter,
4349 Object* setter, 4362 Object* setter,
4350 PropertyAttributes attributes) { 4363 PropertyAttributes attributes) {
4351 switch (GetElementsKind()) { 4364 switch (GetElementsKind()) {
4352 case FAST_SMI_ONLY_ELEMENTS: 4365 case FAST_SMI_ELEMENTS:
4353 case FAST_ELEMENTS: 4366 case FAST_ELEMENTS:
4354 case FAST_DOUBLE_ELEMENTS: 4367 case FAST_DOUBLE_ELEMENTS:
4368 case FAST_HOLEY_SMI_ELEMENTS:
4369 case FAST_HOLEY_ELEMENTS:
4370 case FAST_HOLEY_DOUBLE_ELEMENTS:
4355 break; 4371 break;
4356 case EXTERNAL_PIXEL_ELEMENTS: 4372 case EXTERNAL_PIXEL_ELEMENTS:
4357 case EXTERNAL_BYTE_ELEMENTS: 4373 case EXTERNAL_BYTE_ELEMENTS:
4358 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4374 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4359 case EXTERNAL_SHORT_ELEMENTS: 4375 case EXTERNAL_SHORT_ELEMENTS:
4360 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4376 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
4361 case EXTERNAL_INT_ELEMENTS: 4377 case EXTERNAL_INT_ELEMENTS:
4362 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4378 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
4363 case EXTERNAL_FLOAT_ELEMENTS: 4379 case EXTERNAL_FLOAT_ELEMENTS:
4364 case EXTERNAL_DOUBLE_ELEMENTS: 4380 case EXTERNAL_DOUBLE_ELEMENTS:
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
4461 accessors->SetComponents(getter, setter); 4477 accessors->SetComponents(getter, setter);
4462 return SetPropertyCallback(name, accessors, attributes); 4478 return SetPropertyCallback(name, accessors, attributes);
4463 } 4479 }
4464 4480
4465 4481
4466 bool JSObject::CanSetCallback(String* name) { 4482 bool JSObject::CanSetCallback(String* name) {
4467 ASSERT(!IsAccessCheckNeeded() || 4483 ASSERT(!IsAccessCheckNeeded() ||
4468 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); 4484 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET));
4469 4485
4470 // Check if there is an API defined callback object which prohibits 4486 // Check if there is an API defined callback object which prohibits
4471 // callback overwriting in this object or it's prototype chain. 4487 // callback overwriting in this object or its prototype chain.
4472 // This mechanism is needed for instance in a browser setting, where 4488 // This mechanism is needed for instance in a browser setting, where
4473 // certain accessors such as window.location should not be allowed 4489 // certain accessors such as window.location should not be allowed
4474 // to be overwritten because allowing overwriting could potentially 4490 // to be overwritten because allowing overwriting could potentially
4475 // cause security problems. 4491 // cause security problems.
4476 LookupResult callback_result(GetIsolate()); 4492 LookupResult callback_result(GetIsolate());
4477 LookupCallback(name, &callback_result); 4493 LookupCallback(name, &callback_result);
4478 if (callback_result.IsProperty()) { 4494 if (callback_result.IsProperty()) {
4479 Object* obj = callback_result.GetCallbackObject(); 4495 Object* obj = callback_result.GetCallbackObject();
4480 if (obj->IsAccessorInfo() && 4496 if (obj->IsAccessorInfo() &&
4481 AccessorInfo::cast(obj)->prohibits_overwriting()) { 4497 AccessorInfo::cast(obj)->prohibits_overwriting()) {
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
4783 } 4799 }
4784 4800
4785 uint32_t index = 0; 4801 uint32_t index = 0;
4786 bool is_element = name->AsArrayIndex(&index); 4802 bool is_element = name->AsArrayIndex(&index);
4787 4803
4788 if (is_element) { 4804 if (is_element) {
4789 if (IsJSArray()) return isolate->heap()->undefined_value(); 4805 if (IsJSArray()) return isolate->heap()->undefined_value();
4790 4806
4791 // Accessors overwrite previous callbacks (cf. with getters/setters). 4807 // Accessors overwrite previous callbacks (cf. with getters/setters).
4792 switch (GetElementsKind()) { 4808 switch (GetElementsKind()) {
4793 case FAST_SMI_ONLY_ELEMENTS: 4809 case FAST_SMI_ELEMENTS:
4794 case FAST_ELEMENTS: 4810 case FAST_ELEMENTS:
4795 case FAST_DOUBLE_ELEMENTS: 4811 case FAST_DOUBLE_ELEMENTS:
4812 case FAST_HOLEY_SMI_ELEMENTS:
4813 case FAST_HOLEY_ELEMENTS:
4814 case FAST_HOLEY_DOUBLE_ELEMENTS:
4796 break; 4815 break;
4797 case EXTERNAL_PIXEL_ELEMENTS: 4816 case EXTERNAL_PIXEL_ELEMENTS:
4798 case EXTERNAL_BYTE_ELEMENTS: 4817 case EXTERNAL_BYTE_ELEMENTS:
4799 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4818 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4800 case EXTERNAL_SHORT_ELEMENTS: 4819 case EXTERNAL_SHORT_ELEMENTS:
4801 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4820 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
4802 case EXTERNAL_INT_ELEMENTS: 4821 case EXTERNAL_INT_ELEMENTS:
4803 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4822 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
4804 case EXTERNAL_FLOAT_ELEMENTS: 4823 case EXTERNAL_FLOAT_ELEMENTS:
4805 case EXTERNAL_DOUBLE_ELEMENTS: 4824 case EXTERNAL_DOUBLE_ELEMENTS:
(...skipping 3832 matching lines...) Expand 10 before | Expand all | Expand 10 after
8638 PrintF("RelocInfo (size = %d)\n", relocation_size()); 8657 PrintF("RelocInfo (size = %d)\n", relocation_size());
8639 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); 8658 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out);
8640 PrintF(out, "\n"); 8659 PrintF(out, "\n");
8641 } 8660 }
8642 #endif // ENABLE_DISASSEMBLER 8661 #endif // ENABLE_DISASSEMBLER
8643 8662
8644 8663
8645 MaybeObject* JSObject::SetFastElementsCapacityAndLength( 8664 MaybeObject* JSObject::SetFastElementsCapacityAndLength(
8646 int capacity, 8665 int capacity,
8647 int length, 8666 int length,
8648 SetFastElementsCapacityMode set_capacity_mode) { 8667 SetFastElementsCapacitySmiMode smi_mode) {
8649 Heap* heap = GetHeap(); 8668 Heap* heap = GetHeap();
8650 // We should never end in here with a pixel or external array. 8669 // We should never end in here with a pixel or external array.
8651 ASSERT(!HasExternalArrayElements()); 8670 ASSERT(!HasExternalArrayElements());
8652 8671
8653 // Allocate a new fast elements backing store. 8672 // Allocate a new fast elements backing store.
8654 FixedArray* new_elements; 8673 FixedArray* new_elements;
8655 { MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity); 8674 { MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity);
8656 if (!maybe->To(&new_elements)) return maybe; 8675 if (!maybe->To(&new_elements)) return maybe;
8657 } 8676 }
8658 8677
8659 // Find the new map to use for this object if there is a map change. 8678 ElementsKind elements_kind = GetElementsKind();
8660 Map* new_map = NULL; 8679 ElementsKind new_elements_kind;
8661 if (elements()->map() != heap->non_strict_arguments_elements_map()) { 8680 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it,
8662 // The resized array has FAST_SMI_ONLY_ELEMENTS if the capacity mode forces 8681 // or if it's allowed and the old elements array contained only SMIs.
8663 // it, or if it's allowed and the old elements array contained only SMIs. 8682 bool has_fast_smi_elements =
8664 bool has_fast_smi_only_elements = 8683 (smi_mode == kForceSmiOnlyElements) ||
8665 (set_capacity_mode == kForceSmiOnlyElements) || 8684 ((smi_mode == kAllowSmiOnlyElements) && HasFastSmiElements());
8666 ((set_capacity_mode == kAllowSmiOnlyElements) && 8685 if (has_fast_smi_elements) {
8667 (elements()->map()->has_fast_smi_only_elements() || 8686 if (IsHoleyElementsKind(elements_kind)) {
8668 elements() == heap->empty_fixed_array())); 8687 new_elements_kind = FAST_HOLEY_SMI_ELEMENTS;
8669 ElementsKind elements_kind = has_fast_smi_only_elements 8688 } else {
8670 ? FAST_SMI_ONLY_ELEMENTS 8689 new_elements_kind = FAST_SMI_ELEMENTS;
8671 : FAST_ELEMENTS; 8690 }
8672 MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind); 8691 } else {
8673 if (!maybe->To(&new_map)) return maybe; 8692 if (IsHoleyElementsKind(elements_kind)) {
8693 new_elements_kind = FAST_HOLEY_ELEMENTS;
8694 } else {
8695 new_elements_kind = FAST_ELEMENTS;
8696 }
8674 } 8697 }
8675
8676 FixedArrayBase* old_elements = elements(); 8698 FixedArrayBase* old_elements = elements();
8677 ElementsKind elements_kind = GetElementsKind();
8678 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind); 8699 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
8679 ElementsKind to_kind = (elements_kind == FAST_SMI_ONLY_ELEMENTS) 8700 accessor->CopyElements(this, new_elements, new_elements_kind);
8680 ? FAST_SMI_ONLY_ELEMENTS
8681 : FAST_ELEMENTS;
8682 // int copy_size = Min(old_elements_raw->length(), new_elements->length());
8683 accessor->CopyElements(this, new_elements, to_kind);
8684 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) { 8701 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
8702 Map* new_map = map();
8703 if (new_elements_kind != elements_kind) {
8704 MaybeObject* maybe =
8705 GetElementsTransitionMap(GetIsolate(), new_elements_kind);
8706 if (!maybe->To(&new_map)) return maybe;
8707 }
8708 ValidateElements();
8685 set_map_and_elements(new_map, new_elements); 8709 set_map_and_elements(new_map, new_elements);
8686 } else { 8710 } else {
8687 FixedArray* parameter_map = FixedArray::cast(old_elements); 8711 FixedArray* parameter_map = FixedArray::cast(old_elements);
8688 parameter_map->set(1, new_elements); 8712 parameter_map->set(1, new_elements);
8689 } 8713 }
8690 8714
8691 if (FLAG_trace_elements_transitions) { 8715 if (FLAG_trace_elements_transitions) {
8692 PrintElementsTransition(stdout, elements_kind, old_elements, 8716 PrintElementsTransition(stdout, elements_kind, old_elements,
8693 GetElementsKind(), new_elements); 8717 GetElementsKind(), new_elements);
8694 } 8718 }
8695 8719
8696 // Update the length if necessary.
8697 if (IsJSArray()) { 8720 if (IsJSArray()) {
8698 JSArray::cast(this)->set_length(Smi::FromInt(length)); 8721 JSArray::cast(this)->set_length(Smi::FromInt(length));
8699 } 8722 }
8700
8701 return new_elements; 8723 return new_elements;
8702 } 8724 }
8703 8725
8704 8726
8705 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( 8727 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
8706 int capacity, 8728 int capacity,
8707 int length) { 8729 int length) {
8708 Heap* heap = GetHeap(); 8730 Heap* heap = GetHeap();
8709 // We should never end in here with a pixel or external array. 8731 // We should never end in here with a pixel or external array.
8710 ASSERT(!HasExternalArrayElements()); 8732 ASSERT(!HasExternalArrayElements());
8711 8733
8712 FixedDoubleArray* elems; 8734 FixedDoubleArray* elems;
8713 { MaybeObject* maybe_obj = 8735 { MaybeObject* maybe_obj =
8714 heap->AllocateUninitializedFixedDoubleArray(capacity); 8736 heap->AllocateUninitializedFixedDoubleArray(capacity);
8715 if (!maybe_obj->To(&elems)) return maybe_obj; 8737 if (!maybe_obj->To(&elems)) return maybe_obj;
8716 } 8738 }
8717 8739
8740 ElementsKind elements_kind = GetElementsKind();
8741 ElementsKind new_elements_kind = elements_kind;
8742 if (IsHoleyElementsKind(elements_kind)) {
8743 new_elements_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
8744 } else {
8745 new_elements_kind = FAST_DOUBLE_ELEMENTS;
8746 }
8747
8718 Map* new_map; 8748 Map* new_map;
8719 { MaybeObject* maybe_obj = 8749 { MaybeObject* maybe_obj =
8720 GetElementsTransitionMap(heap->isolate(), FAST_DOUBLE_ELEMENTS); 8750 GetElementsTransitionMap(heap->isolate(), new_elements_kind);
8721 if (!maybe_obj->To(&new_map)) return maybe_obj; 8751 if (!maybe_obj->To(&new_map)) return maybe_obj;
8722 } 8752 }
8723 8753
8724 FixedArrayBase* old_elements = elements(); 8754 FixedArrayBase* old_elements = elements();
8725 ElementsKind elements_kind = GetElementsKind();
8726 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind); 8755 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
8727 accessor->CopyElements(this, elems, FAST_DOUBLE_ELEMENTS); 8756 accessor->CopyElements(this, elems, FAST_DOUBLE_ELEMENTS);
8728 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) { 8757 if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
8758 ValidateElements();
8729 set_map_and_elements(new_map, elems); 8759 set_map_and_elements(new_map, elems);
8730 } else { 8760 } else {
8731 FixedArray* parameter_map = FixedArray::cast(old_elements); 8761 FixedArray* parameter_map = FixedArray::cast(old_elements);
8732 parameter_map->set(1, elems); 8762 parameter_map->set(1, elems);
8733 } 8763 }
8734 8764
8735 if (FLAG_trace_elements_transitions) { 8765 if (FLAG_trace_elements_transitions) {
8736 PrintElementsTransition(stdout, elements_kind, old_elements, 8766 PrintElementsTransition(stdout, elements_kind, old_elements,
8737 FAST_DOUBLE_ELEMENTS, elems); 8767 GetElementsKind(), elems);
8738 } 8768 }
8739 8769
8740 if (IsJSArray()) { 8770 if (IsJSArray()) {
8741 JSArray::cast(this)->set_length(Smi::FromInt(length)); 8771 JSArray::cast(this)->set_length(Smi::FromInt(length));
8742 } 8772 }
8743 8773
8744 return this; 8774 return this;
8745 } 8775 }
8746 8776
8747 8777
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
9007 return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT 9037 return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT
9008 : UNDEFINED_ELEMENT; 9038 : UNDEFINED_ELEMENT;
9009 } 9039 }
9010 9040
9011 // Handle [] on String objects. 9041 // Handle [] on String objects.
9012 if (this->IsStringObjectWithCharacterAt(index)) { 9042 if (this->IsStringObjectWithCharacterAt(index)) {
9013 return STRING_CHARACTER_ELEMENT; 9043 return STRING_CHARACTER_ELEMENT;
9014 } 9044 }
9015 9045
9016 switch (GetElementsKind()) { 9046 switch (GetElementsKind()) {
9017 case FAST_SMI_ONLY_ELEMENTS: 9047 case FAST_SMI_ELEMENTS:
9018 case FAST_ELEMENTS: { 9048 case FAST_ELEMENTS:
9049 case FAST_HOLEY_SMI_ELEMENTS:
9050 case FAST_HOLEY_ELEMENTS: {
9019 uint32_t length = IsJSArray() ? 9051 uint32_t length = IsJSArray() ?
9020 static_cast<uint32_t> 9052 static_cast<uint32_t>
9021 (Smi::cast(JSArray::cast(this)->length())->value()) : 9053 (Smi::cast(JSArray::cast(this)->length())->value()) :
9022 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 9054 static_cast<uint32_t>(FixedArray::cast(elements())->length());
9023 if ((index < length) && 9055 if ((index < length) &&
9024 !FixedArray::cast(elements())->get(index)->IsTheHole()) { 9056 !FixedArray::cast(elements())->get(index)->IsTheHole()) {
9025 return FAST_ELEMENT; 9057 return FAST_ELEMENT;
9026 } 9058 }
9027 break; 9059 break;
9028 } 9060 }
9029 case FAST_DOUBLE_ELEMENTS: { 9061 case FAST_DOUBLE_ELEMENTS:
9062 case FAST_HOLEY_DOUBLE_ELEMENTS: {
9030 uint32_t length = IsJSArray() ? 9063 uint32_t length = IsJSArray() ?
9031 static_cast<uint32_t> 9064 static_cast<uint32_t>
9032 (Smi::cast(JSArray::cast(this)->length())->value()) : 9065 (Smi::cast(JSArray::cast(this)->length())->value()) :
9033 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length()); 9066 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
9034 if ((index < length) && 9067 if ((index < length) &&
9035 !FixedDoubleArray::cast(elements())->is_the_hole(index)) { 9068 !FixedDoubleArray::cast(elements())->is_the_hole(index)) {
9036 return FAST_ELEMENT; 9069 return FAST_ELEMENT;
9037 } 9070 }
9038 break; 9071 break;
9039 } 9072 }
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
9303 } 9336 }
9304 9337
9305 9338
9306 // Adding n elements in fast case is O(n*n). 9339 // Adding n elements in fast case is O(n*n).
9307 // Note: revisit design to have dual undefined values to capture absent 9340 // Note: revisit design to have dual undefined values to capture absent
9308 // elements. 9341 // elements.
9309 MaybeObject* JSObject::SetFastElement(uint32_t index, 9342 MaybeObject* JSObject::SetFastElement(uint32_t index,
9310 Object* value, 9343 Object* value,
9311 StrictModeFlag strict_mode, 9344 StrictModeFlag strict_mode,
9312 bool check_prototype) { 9345 bool check_prototype) {
9313 ASSERT(HasFastTypeElements() || 9346 ASSERT(HasFastSmiOrObjectElements() ||
9314 HasFastArgumentsElements()); 9347 HasFastArgumentsElements());
9315 9348
9316 FixedArray* backing_store = FixedArray::cast(elements()); 9349 FixedArray* backing_store = FixedArray::cast(elements());
9317 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { 9350 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) {
9318 backing_store = FixedArray::cast(backing_store->get(1)); 9351 backing_store = FixedArray::cast(backing_store->get(1));
9319 } else { 9352 } else {
9320 MaybeObject* maybe = EnsureWritableFastElements(); 9353 MaybeObject* maybe = EnsureWritableFastElements();
9321 if (!maybe->To(&backing_store)) return maybe; 9354 if (!maybe->To(&backing_store)) return maybe;
9322 } 9355 }
9323 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); 9356 uint32_t capacity = static_cast<uint32_t>(backing_store->length());
9324 9357
9325 if (check_prototype && 9358 if (check_prototype &&
9326 (index >= capacity || backing_store->get(index)->IsTheHole())) { 9359 (index >= capacity || backing_store->get(index)->IsTheHole())) {
9327 bool found; 9360 bool found;
9328 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, 9361 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index,
9329 value, 9362 value,
9330 &found, 9363 &found,
9331 strict_mode); 9364 strict_mode);
9332 if (found) return result; 9365 if (found) return result;
9333 } 9366 }
9334 9367
9335 uint32_t new_capacity = capacity; 9368 uint32_t new_capacity = capacity;
9336 // Check if the length property of this object needs to be updated. 9369 // Check if the length property of this object needs to be updated.
9337 uint32_t array_length = 0; 9370 uint32_t array_length = 0;
9338 bool must_update_array_length = false; 9371 bool must_update_array_length = false;
9372 bool introduces_holes = true;
9339 if (IsJSArray()) { 9373 if (IsJSArray()) {
9340 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); 9374 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length));
9375 introduces_holes = index > array_length;
9341 if (index >= array_length) { 9376 if (index >= array_length) {
9342 must_update_array_length = true; 9377 must_update_array_length = true;
9343 array_length = index + 1; 9378 array_length = index + 1;
9344 } 9379 }
9380 } else {
9381 introduces_holes = index >= capacity;
9345 } 9382 }
9383
9384 // If the array is growing, and it's not growth by a single element at the
9385 // end, make sure that the ElementsKind is HOLEY.
9386 ElementsKind elements_kind = GetElementsKind();
9387 if (introduces_holes &&
9388 IsFastElementsKind(elements_kind) &&
9389 !IsFastHoleyElementsKind(elements_kind)) {
9390 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind);
9391 MaybeObject* maybe = TransitionElementsKind(transitioned_kind);
9392 if (maybe->IsFailure()) return maybe;
9393 }
9394
9346 // Check if the capacity of the backing store needs to be increased, or if 9395 // Check if the capacity of the backing store needs to be increased, or if
9347 // a transition to slow elements is necessary. 9396 // a transition to slow elements is necessary.
9348 if (index >= capacity) { 9397 if (index >= capacity) {
9349 bool convert_to_slow = true; 9398 bool convert_to_slow = true;
9350 if ((index - capacity) < kMaxGap) { 9399 if ((index - capacity) < kMaxGap) {
9351 new_capacity = NewElementsCapacity(index + 1); 9400 new_capacity = NewElementsCapacity(index + 1);
9352 ASSERT(new_capacity > index); 9401 ASSERT(new_capacity > index);
9353 if (!ShouldConvertToSlowElements(new_capacity)) { 9402 if (!ShouldConvertToSlowElements(new_capacity)) {
9354 convert_to_slow = false; 9403 convert_to_slow = false;
9355 } 9404 }
9356 } 9405 }
9357 if (convert_to_slow) { 9406 if (convert_to_slow) {
9358 MaybeObject* result = NormalizeElements(); 9407 MaybeObject* result = NormalizeElements();
9359 if (result->IsFailure()) return result; 9408 if (result->IsFailure()) return result;
9360 return SetDictionaryElement(index, value, NONE, strict_mode, 9409 return SetDictionaryElement(index, value, NONE, strict_mode,
9361 check_prototype); 9410 check_prototype);
9362 } 9411 }
9363 } 9412 }
9364 // Convert to fast double elements if appropriate. 9413 // Convert to fast double elements if appropriate.
9365 if (HasFastSmiOnlyElements() && !value->IsSmi() && value->IsNumber()) { 9414 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) {
9366 MaybeObject* maybe = 9415 MaybeObject* maybe =
9367 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); 9416 SetFastDoubleElementsCapacityAndLength(new_capacity,
9417 array_length);
Jakob Kummerow 2012/05/13 21:55:27 nit: why the line break?
danno 2012/05/22 11:05:21 Done.
9368 if (maybe->IsFailure()) return maybe; 9418 if (maybe->IsFailure()) return maybe;
9369 FixedDoubleArray::cast(elements())->set(index, value->Number()); 9419 FixedDoubleArray::cast(elements())->set(index, value->Number());
9420 ValidateElements();
9370 return value; 9421 return value;
9371 } 9422 }
9372 // Change elements kind from SMI_ONLY to generic FAST if necessary. 9423 // Change elements kind from Smi-only to generic FAST if necessary.
9373 if (HasFastSmiOnlyElements() && !value->IsSmi()) { 9424 if (HasFastSmiElements() && !value->IsSmi()) {
9374 Map* new_map; 9425 Map* new_map;
9375 { MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), 9426 ElementsKind kind = HasFastHoleyElements()
9376 FAST_ELEMENTS); 9427 ? FAST_HOLEY_ELEMENTS
9377 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 9428 : FAST_ELEMENTS;
9378 } 9429 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(),
9430 kind);
9431 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
9432
9379 set_map(new_map); 9433 set_map(new_map);
9380 if (FLAG_trace_elements_transitions) {
Jakob Kummerow 2012/05/13 21:55:27 I don't see why you would remove this.
danno 2012/05/22 11:05:21 Because it's a dupe of the transition printing don
9381 PrintElementsTransition(stdout, FAST_SMI_ONLY_ELEMENTS, elements(),
9382 FAST_ELEMENTS, elements());
9383 }
9384 } 9434 }
9385 // Increase backing store capacity if that's been decided previously. 9435 // Increase backing store capacity if that's been decided previously.
9386 if (new_capacity != capacity) { 9436 if (new_capacity != capacity) {
9387 FixedArray* new_elements; 9437 FixedArray* new_elements;
9388 SetFastElementsCapacityMode set_capacity_mode = 9438 SetFastElementsCapacitySmiMode smi_mode =
9389 value->IsSmi() && HasFastSmiOnlyElements() 9439 value->IsSmi() && HasFastSmiElements()
9390 ? kAllowSmiOnlyElements 9440 ? kAllowSmiOnlyElements
9391 : kDontAllowSmiOnlyElements; 9441 : kDontAllowSmiOnlyElements;
9392 { MaybeObject* maybe = 9442 { MaybeObject* maybe =
9393 SetFastElementsCapacityAndLength(new_capacity, 9443 SetFastElementsCapacityAndLength(new_capacity,
9394 array_length, 9444 array_length,
9395 set_capacity_mode); 9445 smi_mode);
9396 if (!maybe->To(&new_elements)) return maybe; 9446 if (!maybe->To(&new_elements)) return maybe;
9397 } 9447 }
9398 new_elements->set(index, value); 9448 new_elements->set(index, value);
9449 #if DEBUG
9450 ValidateElements();
Jakob Kummerow 2012/05/13 21:55:27 Calls to ValidateElements() aren't wrapped in an #
danno 2012/05/22 11:05:21 Done.
9451 #endif
9399 return value; 9452 return value;
9400 } 9453 }
9454
9401 // Finally, set the new element and length. 9455 // Finally, set the new element and length.
9402 ASSERT(elements()->IsFixedArray()); 9456 ASSERT(elements()->IsFixedArray());
9403 backing_store->set(index, value); 9457 backing_store->set(index, value);
9404 if (must_update_array_length) { 9458 if (must_update_array_length) {
9405 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); 9459 JSArray::cast(this)->set_length(Smi::FromInt(array_length));
9406 } 9460 }
9407 return value; 9461 return value;
9408 } 9462 }
9409 9463
9410 9464
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
9514 } 9568 }
9515 9569
9516 // Attempt to put this object back in fast case. 9570 // Attempt to put this object back in fast case.
9517 if (ShouldConvertToFastElements()) { 9571 if (ShouldConvertToFastElements()) {
9518 uint32_t new_length = 0; 9572 uint32_t new_length = 0;
9519 if (IsJSArray()) { 9573 if (IsJSArray()) {
9520 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); 9574 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
9521 } else { 9575 } else {
9522 new_length = dictionary->max_number_key() + 1; 9576 new_length = dictionary->max_number_key() + 1;
9523 } 9577 }
9524 SetFastElementsCapacityMode set_capacity_mode = FLAG_smi_only_arrays 9578 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays
9525 ? kAllowSmiOnlyElements 9579 ? kAllowSmiOnlyElements
9526 : kDontAllowSmiOnlyElements; 9580 : kDontAllowSmiOnlyElements;
9527 bool has_smi_only_elements = false; 9581 bool has_smi_only_elements = false;
9528 bool should_convert_to_fast_double_elements = 9582 bool should_convert_to_fast_double_elements =
9529 ShouldConvertToFastDoubleElements(&has_smi_only_elements); 9583 ShouldConvertToFastDoubleElements(&has_smi_only_elements);
9530 if (has_smi_only_elements) { 9584 if (has_smi_only_elements) {
9531 set_capacity_mode = kForceSmiOnlyElements; 9585 smi_mode = kForceSmiOnlyElements;
9532 } 9586 }
9533 MaybeObject* result = should_convert_to_fast_double_elements 9587 MaybeObject* result = should_convert_to_fast_double_elements
9534 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length) 9588 ? SetFastDoubleElementsCapacityAndLength(new_length,
Jakob Kummerow 2012/05/13 21:55:27 nit: why the line break?
danno 2012/05/22 11:05:21 Done.
9589 new_length)
9535 : SetFastElementsCapacityAndLength(new_length, 9590 : SetFastElementsCapacityAndLength(new_length,
9536 new_length, 9591 new_length,
9537 set_capacity_mode); 9592 smi_mode);
9593 ValidateElements();
9538 if (result->IsFailure()) return result; 9594 if (result->IsFailure()) return result;
9539 #ifdef DEBUG 9595 #ifdef DEBUG
9540 if (FLAG_trace_normalization) { 9596 if (FLAG_trace_normalization) {
9541 PrintF("Object elements are fast case again:\n"); 9597 PrintF("Object elements are fast case again:\n");
9542 Print(); 9598 Print();
9543 } 9599 }
9544 #endif 9600 #endif
9545 } 9601 }
9546 return value; 9602 return value;
9547 } 9603 }
(...skipping 18 matching lines...) Expand all
9566 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, 9622 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index,
9567 value, 9623 value,
9568 &found, 9624 &found,
9569 strict_mode); 9625 strict_mode);
9570 if (found) return result; 9626 if (found) return result;
9571 } 9627 }
9572 9628
9573 // If the value object is not a heap number, switch to fast elements and try 9629 // If the value object is not a heap number, switch to fast elements and try
9574 // again. 9630 // again.
9575 bool value_is_smi = value->IsSmi(); 9631 bool value_is_smi = value->IsSmi();
9632 bool introduces_holes = true;
9633 uint32_t length = elms_length;
9634 if (IsJSArray()) {
9635 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
9636 introduces_holes = index > length;
9637 } else {
9638 introduces_holes = index >= elms_length;
9639 }
9640
9576 if (!value->IsNumber()) { 9641 if (!value->IsNumber()) {
9577 Object* obj;
9578 uint32_t length = elms_length;
9579 if (IsJSArray()) {
9580 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
9581 }
9582 MaybeObject* maybe_obj = SetFastElementsCapacityAndLength( 9642 MaybeObject* maybe_obj = SetFastElementsCapacityAndLength(
9583 elms_length, 9643 elms_length,
9584 length, 9644 length,
9585 kDontAllowSmiOnlyElements); 9645 kDontAllowSmiOnlyElements);
9586 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9646 if (maybe_obj->IsFailure()) return maybe_obj;
9587 return SetFastElement(index, 9647 maybe_obj = SetFastElement(index, value, strict_mode, check_prototype);
9588 value, 9648 if (maybe_obj->IsFailure()) return maybe_obj;
9589 strict_mode, 9649 ValidateElements();
9590 check_prototype); 9650 return maybe_obj;
9591 } 9651 }
9592 9652
9593 double double_value = value_is_smi 9653 double double_value = value_is_smi
9594 ? static_cast<double>(Smi::cast(value)->value()) 9654 ? static_cast<double>(Smi::cast(value)->value())
9595 : HeapNumber::cast(value)->value(); 9655 : HeapNumber::cast(value)->value();
9596 9656
9657 // If the array is growing, and it's not growth by a single element at the
9658 // end, make sure that the ElementsKind is HOLEY.
9659 ElementsKind elements_kind = GetElementsKind();
9660 if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) {
9661 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind);
9662 MaybeObject* maybe = TransitionElementsKind(transitioned_kind);
9663 if (maybe->IsFailure()) return maybe;
9664 }
9665
9597 // Check whether there is extra space in the fixed array. 9666 // Check whether there is extra space in the fixed array.
9598 if (index < elms_length) { 9667 if (index < elms_length) {
9599 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); 9668 FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
9600 elms->set(index, double_value); 9669 elms->set(index, double_value);
9601 if (IsJSArray()) { 9670 if (IsJSArray()) {
9602 // Update the length of the array if needed. 9671 // Update the length of the array if needed.
9603 uint32_t array_length = 0; 9672 uint32_t array_length = 0;
9604 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); 9673 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length));
9605 if (index >= array_length) { 9674 if (index >= array_length) {
9606 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); 9675 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
9607 } 9676 }
9608 } 9677 }
9609 return value; 9678 return value;
9610 } 9679 }
9611 9680
9612 // Allow gap in fast case. 9681 // Allow gap in fast case.
9613 if ((index - elms_length) < kMaxGap) { 9682 if ((index - elms_length) < kMaxGap) {
9614 // Try allocating extra space. 9683 // Try allocating extra space.
9615 int new_capacity = NewElementsCapacity(index+1); 9684 int new_capacity = NewElementsCapacity(index+1);
9616 if (!ShouldConvertToSlowElements(new_capacity)) { 9685 if (!ShouldConvertToSlowElements(new_capacity)) {
9617 ASSERT(static_cast<uint32_t>(new_capacity) > index); 9686 ASSERT(static_cast<uint32_t>(new_capacity) > index);
9618 Object* obj; 9687 MaybeObject* maybe_obj =
9619 { MaybeObject* maybe_obj = 9688 SetFastDoubleElementsCapacityAndLength(new_capacity, index + 1);
9620 SetFastDoubleElementsCapacityAndLength(new_capacity, 9689 if (maybe_obj->IsFailure()) return maybe_obj;
9621 index + 1);
9622 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
9623 }
9624 FixedDoubleArray::cast(elements())->set(index, double_value); 9690 FixedDoubleArray::cast(elements())->set(index, double_value);
9691 ValidateElements();
9625 return value; 9692 return value;
9626 } 9693 }
9627 } 9694 }
9628 9695
9629 // Otherwise default to slow case. 9696 // Otherwise default to slow case.
9630 ASSERT(HasFastDoubleElements()); 9697 ASSERT(HasFastDoubleElements());
9631 ASSERT(map()->has_fast_double_elements()); 9698 ASSERT(map()->has_fast_double_elements());
9632 ASSERT(elements()->IsFixedDoubleArray()); 9699 ASSERT(elements()->IsFixedDoubleArray());
9633 Object* obj; 9700 Object* obj;
9634 { MaybeObject* maybe_obj = NormalizeElements(); 9701 { MaybeObject* maybe_obj = NormalizeElements();
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
9758 Object* value, 9825 Object* value,
9759 PropertyAttributes attr, 9826 PropertyAttributes attr,
9760 StrictModeFlag strict_mode, 9827 StrictModeFlag strict_mode,
9761 bool check_prototype, 9828 bool check_prototype,
9762 SetPropertyMode set_mode) { 9829 SetPropertyMode set_mode) {
9763 ASSERT(HasDictionaryElements() || 9830 ASSERT(HasDictionaryElements() ||
9764 HasDictionaryArgumentsElements() || 9831 HasDictionaryArgumentsElements() ||
9765 (attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); 9832 (attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0);
9766 Isolate* isolate = GetIsolate(); 9833 Isolate* isolate = GetIsolate();
9767 switch (GetElementsKind()) { 9834 switch (GetElementsKind()) {
9768 case FAST_SMI_ONLY_ELEMENTS: 9835 case FAST_SMI_ELEMENTS:
9769 case FAST_ELEMENTS: 9836 case FAST_ELEMENTS:
9837 case FAST_HOLEY_SMI_ELEMENTS:
9838 case FAST_HOLEY_ELEMENTS:
9770 return SetFastElement(index, value, strict_mode, check_prototype); 9839 return SetFastElement(index, value, strict_mode, check_prototype);
9771 case FAST_DOUBLE_ELEMENTS: 9840 case FAST_DOUBLE_ELEMENTS:
9841 case FAST_HOLEY_DOUBLE_ELEMENTS:
9772 return SetFastDoubleElement(index, value, strict_mode, check_prototype); 9842 return SetFastDoubleElement(index, value, strict_mode, check_prototype);
9773 case EXTERNAL_PIXEL_ELEMENTS: { 9843 case EXTERNAL_PIXEL_ELEMENTS: {
9774 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 9844 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
9775 return pixels->SetValue(index, value); 9845 return pixels->SetValue(index, value);
9776 } 9846 }
9777 case EXTERNAL_BYTE_ELEMENTS: { 9847 case EXTERNAL_BYTE_ELEMENTS: {
9778 ExternalByteArray* array = ExternalByteArray::cast(elements()); 9848 ExternalByteArray* array = ExternalByteArray::cast(elements());
9779 return array->SetValue(index, value); 9849 return array->SetValue(index, value);
9780 } 9850 }
9781 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { 9851 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
9852 ElementsKind to_kind) { 9922 ElementsKind to_kind) {
9853 CALL_HEAP_FUNCTION(object->GetIsolate(), 9923 CALL_HEAP_FUNCTION(object->GetIsolate(),
9854 object->TransitionElementsKind(to_kind), 9924 object->TransitionElementsKind(to_kind),
9855 Object); 9925 Object);
9856 } 9926 }
9857 9927
9858 9928
9859 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { 9929 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
9860 ElementsKind from_kind = map()->elements_kind(); 9930 ElementsKind from_kind = map()->elements_kind();
9861 9931
9932 if (IsFastHoleyElementsKind(from_kind)) {
9933 to_kind = GetHoleyElementsKind(to_kind);
9934 }
9935
9862 Isolate* isolate = GetIsolate(); 9936 Isolate* isolate = GetIsolate();
9863 if (from_kind == FAST_SMI_ONLY_ELEMENTS && 9937
9864 (to_kind == FAST_ELEMENTS || 9938 if (elements() == isolate->heap()->empty_fixed_array() ||
9865 elements() == isolate->heap()->empty_fixed_array())) { 9939 (IsFastSmiOrObjectElementsKind(from_kind) &&
9940 IsFastSmiOrObjectElementsKind(to_kind)) ||
9941 (from_kind == FAST_DOUBLE_ELEMENTS &&
9942 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) {
9943 // No change is needed to the elements() buffer, the transition
9944 // only requires a map change.
9866 MaybeObject* maybe_new_map = GetElementsTransitionMap(isolate, to_kind); 9945 MaybeObject* maybe_new_map = GetElementsTransitionMap(isolate, to_kind);
9867 Map* new_map; 9946 Map* new_map;
9868 if (!maybe_new_map->To(&new_map)) return maybe_new_map; 9947 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
9869 set_map(new_map); 9948 set_map(new_map);
9870 if (FLAG_trace_elements_transitions) { 9949 if (FLAG_trace_elements_transitions) {
9871 FixedArrayBase* elms = FixedArrayBase::cast(elements()); 9950 FixedArrayBase* elms = FixedArrayBase::cast(elements());
9872 PrintElementsTransition(stdout, from_kind, elms, to_kind, elms); 9951 PrintElementsTransition(stdout, from_kind, elms, to_kind, elms);
9873 } 9952 }
9874 return this; 9953 return this;
9875 } 9954 }
9876 9955
9877 FixedArrayBase* elms = FixedArrayBase::cast(elements()); 9956 FixedArrayBase* elms = FixedArrayBase::cast(elements());
9878 uint32_t capacity = static_cast<uint32_t>(elms->length()); 9957 uint32_t capacity = static_cast<uint32_t>(elms->length());
9879 uint32_t length = capacity; 9958 uint32_t length = capacity;
9880 9959
9881 if (IsJSArray()) { 9960 if (IsJSArray()) {
9882 Object* raw_length = JSArray::cast(this)->length(); 9961 Object* raw_length = JSArray::cast(this)->length();
9883 if (raw_length->IsUndefined()) { 9962 if (raw_length->IsUndefined()) {
9884 // If length is undefined, then JSArray is being initialized and has no 9963 // If length is undefined, then JSArray is being initialized and has no
9885 // elements, assume a length of zero. 9964 // elements, assume a length of zero.
9886 length = 0; 9965 length = 0;
9887 } else { 9966 } else {
9888 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); 9967 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
9889 } 9968 }
9890 } 9969 }
9891 9970
9892 if (from_kind == FAST_SMI_ONLY_ELEMENTS && 9971 if (IsFastSmiElementsKind(from_kind) &&
9893 to_kind == FAST_DOUBLE_ELEMENTS) { 9972 IsFastDoubleElementsKind(to_kind)) {
9894 MaybeObject* maybe_result = 9973 MaybeObject* maybe_result =
9895 SetFastDoubleElementsCapacityAndLength(capacity, length); 9974 SetFastDoubleElementsCapacityAndLength(capacity, length);
9896 if (maybe_result->IsFailure()) return maybe_result; 9975 if (maybe_result->IsFailure()) return maybe_result;
9976 ValidateElements();
9897 return this; 9977 return this;
9898 } 9978 }
9899 9979
9900 if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { 9980 if (IsFastDoubleElementsKind(from_kind) &&
9981 IsFastObjectElementsKind(to_kind)) {
9901 MaybeObject* maybe_result = SetFastElementsCapacityAndLength( 9982 MaybeObject* maybe_result = SetFastElementsCapacityAndLength(
9902 capacity, length, kDontAllowSmiOnlyElements); 9983 capacity, length, kDontAllowSmiOnlyElements);
9903 if (maybe_result->IsFailure()) return maybe_result; 9984 if (maybe_result->IsFailure()) return maybe_result;
9985 ValidateElements();
9904 return this; 9986 return this;
9905 } 9987 }
9906 9988
9907 // This method should never be called for any other case than the ones 9989 // This method should never be called for any other case than the ones
9908 // handled above. 9990 // handled above.
9909 UNREACHABLE(); 9991 UNREACHABLE();
9910 return GetIsolate()->heap()->null_value(); 9992 return GetIsolate()->heap()->null_value();
9911 } 9993 }
9912 9994
9913 9995
9914 // static 9996 // static
9915 bool Map::IsValidElementsTransition(ElementsKind from_kind, 9997 bool Map::IsValidElementsTransition(ElementsKind from_kind,
9916 ElementsKind to_kind) { 9998 ElementsKind to_kind) {
9917 return 9999 // Transitions can't go backwards.
9918 (from_kind == FAST_SMI_ONLY_ELEMENTS && 10000 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
9919 (to_kind == FAST_DOUBLE_ELEMENTS || to_kind == FAST_ELEMENTS)) || 10001 return false;
9920 (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS); 10002 }
10003
10004 // Transitions from HOLEY -> PACKED are not allowed.
10005 return !IsFastHoleyElementsKind(from_kind) ||
10006 IsFastHoleyElementsKind(to_kind);
9921 } 10007 }
9922 10008
9923 10009
9924 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, 10010 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index,
9925 Object* value) { 10011 Object* value) {
9926 uint32_t old_len = 0; 10012 uint32_t old_len = 0;
9927 CHECK(length()->ToArrayIndex(&old_len)); 10013 CHECK(length()->ToArrayIndex(&old_len));
9928 // Check to see if we need to update the length. For now, we make 10014 // Check to see if we need to update the length. For now, we make
9929 // sure that the length stays within 32-bits (unsigned). 10015 // sure that the length stays within 32-bits (unsigned).
9930 if (index >= old_len && index != 0xffffffff) { 10016 if (index >= old_len && index != 0xffffffff) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
10001 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); 10087 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
10002 backing_store = FixedArray::cast(backing_store_base); 10088 backing_store = FixedArray::cast(backing_store_base);
10003 if (backing_store->IsDictionary()) { 10089 if (backing_store->IsDictionary()) {
10004 SeededNumberDictionary* dictionary = 10090 SeededNumberDictionary* dictionary =
10005 SeededNumberDictionary::cast(backing_store); 10091 SeededNumberDictionary::cast(backing_store);
10006 *capacity = dictionary->Capacity(); 10092 *capacity = dictionary->Capacity();
10007 *used = dictionary->NumberOfElements(); 10093 *used = dictionary->NumberOfElements();
10008 break; 10094 break;
10009 } 10095 }
10010 // Fall through. 10096 // Fall through.
10011 case FAST_SMI_ONLY_ELEMENTS: 10097 case FAST_SMI_ELEMENTS:
10012 case FAST_ELEMENTS: 10098 case FAST_ELEMENTS:
10099 case FAST_HOLEY_SMI_ELEMENTS:
10100 case FAST_HOLEY_ELEMENTS:
10013 backing_store = FixedArray::cast(backing_store_base); 10101 backing_store = FixedArray::cast(backing_store_base);
10014 *capacity = backing_store->length(); 10102 *capacity = backing_store->length();
10015 for (int i = 0; i < *capacity; ++i) { 10103 for (int i = 0; i < *capacity; ++i) {
10016 if (!backing_store->get(i)->IsTheHole()) ++(*used); 10104 if (!backing_store->get(i)->IsTheHole()) ++(*used);
10017 } 10105 }
10018 break; 10106 break;
10019 case DICTIONARY_ELEMENTS: { 10107 case DICTIONARY_ELEMENTS: {
10020 SeededNumberDictionary* dictionary = 10108 SeededNumberDictionary* dictionary =
10021 SeededNumberDictionary::cast(FixedArray::cast(elements())); 10109 SeededNumberDictionary::cast(FixedArray::cast(elements()));
10022 *capacity = dictionary->Capacity(); 10110 *capacity = dictionary->Capacity();
10023 *used = dictionary->NumberOfElements(); 10111 *used = dictionary->NumberOfElements();
10024 break; 10112 break;
10025 } 10113 }
10026 case FAST_DOUBLE_ELEMENTS: { 10114 case FAST_DOUBLE_ELEMENTS:
10115 case FAST_HOLEY_DOUBLE_ELEMENTS: {
10027 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); 10116 FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
10028 *capacity = elms->length(); 10117 *capacity = elms->length();
10029 for (int i = 0; i < *capacity; i++) { 10118 for (int i = 0; i < *capacity; i++) {
10030 if (!elms->is_the_hole(i)) ++(*used); 10119 if (!elms->is_the_hole(i)) ++(*used);
10031 } 10120 }
10032 break; 10121 break;
10033 } 10122 }
10034 case EXTERNAL_BYTE_ELEMENTS: 10123 case EXTERNAL_BYTE_ELEMENTS:
10035 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 10124 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
10036 case EXTERNAL_SHORT_ELEMENTS: 10125 case EXTERNAL_SHORT_ELEMENTS:
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
10286 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 10375 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
10287 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 10376 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
10288 return false; 10377 return false;
10289 } 10378 }
10290 } 10379 }
10291 10380
10292 // Handle [] on String objects. 10381 // Handle [] on String objects.
10293 if (this->IsStringObjectWithCharacterAt(index)) return true; 10382 if (this->IsStringObjectWithCharacterAt(index)) return true;
10294 10383
10295 switch (GetElementsKind()) { 10384 switch (GetElementsKind()) {
10296 case FAST_SMI_ONLY_ELEMENTS: 10385 case FAST_SMI_ELEMENTS:
10297 case FAST_ELEMENTS: { 10386 case FAST_ELEMENTS:
10298 uint32_t length = IsJSArray() ? 10387 case FAST_HOLEY_SMI_ELEMENTS:
10388 case FAST_HOLEY_ELEMENTS: {
10389 uint32_t length = IsJSArray() ?
10299 static_cast<uint32_t>( 10390 static_cast<uint32_t>(
10300 Smi::cast(JSArray::cast(this)->length())->value()) : 10391 Smi::cast(JSArray::cast(this)->length())->value()) :
10301 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 10392 static_cast<uint32_t>(FixedArray::cast(elements())->length());
10302 return (index < length) && 10393 return (index < length) &&
10303 !FixedArray::cast(elements())->get(index)->IsTheHole(); 10394 !FixedArray::cast(elements())->get(index)->IsTheHole();
10304 } 10395 }
10305 case FAST_DOUBLE_ELEMENTS: { 10396 case FAST_DOUBLE_ELEMENTS:
10397 case FAST_HOLEY_DOUBLE_ELEMENTS: {
10306 uint32_t length = IsJSArray() ? 10398 uint32_t length = IsJSArray() ?
10307 static_cast<uint32_t>( 10399 static_cast<uint32_t>(
10308 Smi::cast(JSArray::cast(this)->length())->value()) : 10400 Smi::cast(JSArray::cast(this)->length())->value()) :
10309 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length()); 10401 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
10310 return (index < length) && 10402 return (index < length) &&
10311 !FixedDoubleArray::cast(elements())->is_the_hole(index); 10403 !FixedDoubleArray::cast(elements())->is_the_hole(index);
10312 break; 10404 break;
10313 } 10405 }
10314 case EXTERNAL_PIXEL_ELEMENTS: { 10406 case EXTERNAL_PIXEL_ELEMENTS: {
10315 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 10407 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
10495 } 10587 }
10496 10588
10497 10589
10498 int JSObject::NumberOfLocalElements(PropertyAttributes filter) { 10590 int JSObject::NumberOfLocalElements(PropertyAttributes filter) {
10499 return GetLocalElementKeys(NULL, filter); 10591 return GetLocalElementKeys(NULL, filter);
10500 } 10592 }
10501 10593
10502 10594
10503 int JSObject::NumberOfEnumElements() { 10595 int JSObject::NumberOfEnumElements() {
10504 // Fast case for objects with no elements. 10596 // Fast case for objects with no elements.
10505 if (!IsJSValue() && HasFastElements()) { 10597 if (!IsJSValue() && HasFastObjectElements()) {
10506 uint32_t length = IsJSArray() ? 10598 uint32_t length = IsJSArray() ?
10507 static_cast<uint32_t>( 10599 static_cast<uint32_t>(
10508 Smi::cast(JSArray::cast(this)->length())->value()) : 10600 Smi::cast(JSArray::cast(this)->length())->value()) :
10509 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 10601 static_cast<uint32_t>(FixedArray::cast(elements())->length());
10510 if (length == 0) return 0; 10602 if (length == 0) return 0;
10511 } 10603 }
10512 // Compute the number of enumerable elements. 10604 // Compute the number of enumerable elements.
10513 return NumberOfLocalElements(static_cast<PropertyAttributes>(DONT_ENUM)); 10605 return NumberOfLocalElements(static_cast<PropertyAttributes>(DONT_ENUM));
10514 } 10606 }
10515 10607
10516 10608
10517 int JSObject::GetLocalElementKeys(FixedArray* storage, 10609 int JSObject::GetLocalElementKeys(FixedArray* storage,
10518 PropertyAttributes filter) { 10610 PropertyAttributes filter) {
10519 int counter = 0; 10611 int counter = 0;
10520 switch (GetElementsKind()) { 10612 switch (GetElementsKind()) {
10521 case FAST_SMI_ONLY_ELEMENTS: 10613 case FAST_SMI_ELEMENTS:
10522 case FAST_ELEMENTS: { 10614 case FAST_ELEMENTS:
10615 case FAST_HOLEY_SMI_ELEMENTS:
10616 case FAST_HOLEY_ELEMENTS: {
10523 int length = IsJSArray() ? 10617 int length = IsJSArray() ?
10524 Smi::cast(JSArray::cast(this)->length())->value() : 10618 Smi::cast(JSArray::cast(this)->length())->value() :
10525 FixedArray::cast(elements())->length(); 10619 FixedArray::cast(elements())->length();
10526 for (int i = 0; i < length; i++) { 10620 for (int i = 0; i < length; i++) {
10527 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { 10621 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) {
10528 if (storage != NULL) { 10622 if (storage != NULL) {
10529 storage->set(counter, Smi::FromInt(i)); 10623 storage->set(counter, Smi::FromInt(i));
10530 } 10624 }
10531 counter++; 10625 counter++;
10532 } 10626 }
10533 } 10627 }
10534 ASSERT(!storage || storage->length() >= counter); 10628 ASSERT(!storage || storage->length() >= counter);
10535 break; 10629 break;
10536 } 10630 }
10537 case FAST_DOUBLE_ELEMENTS: { 10631 case FAST_DOUBLE_ELEMENTS:
10632 case FAST_HOLEY_DOUBLE_ELEMENTS: {
10538 int length = IsJSArray() ? 10633 int length = IsJSArray() ?
10539 Smi::cast(JSArray::cast(this)->length())->value() : 10634 Smi::cast(JSArray::cast(this)->length())->value() :
10540 FixedDoubleArray::cast(elements())->length(); 10635 FixedDoubleArray::cast(elements())->length();
10541 for (int i = 0; i < length; i++) { 10636 for (int i = 0; i < length; i++) {
10542 if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) { 10637 if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) {
10543 if (storage != NULL) { 10638 if (storage != NULL) {
10544 storage->set(counter, Smi::FromInt(i)); 10639 storage->set(counter, Smi::FromInt(i));
10545 } 10640 }
10546 counter++; 10641 counter++;
10547 } 10642 }
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after
11460 // Convert to fast elements containing only the existing properties. 11555 // Convert to fast elements containing only the existing properties.
11461 // Ordering is irrelevant, since we are going to sort anyway. 11556 // Ordering is irrelevant, since we are going to sort anyway.
11462 SeededNumberDictionary* dict = element_dictionary(); 11557 SeededNumberDictionary* dict = element_dictionary();
11463 if (IsJSArray() || dict->requires_slow_elements() || 11558 if (IsJSArray() || dict->requires_slow_elements() ||
11464 dict->max_number_key() >= limit) { 11559 dict->max_number_key() >= limit) {
11465 return PrepareSlowElementsForSort(limit); 11560 return PrepareSlowElementsForSort(limit);
11466 } 11561 }
11467 // Convert to fast elements. 11562 // Convert to fast elements.
11468 11563
11469 Object* obj; 11564 Object* obj;
11470 { MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), 11565 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
11471 FAST_ELEMENTS); 11566 FAST_HOLEY_ELEMENTS);
11472 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 11567 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
11473 }
11474 Map* new_map = Map::cast(obj); 11568 Map* new_map = Map::cast(obj);
11475 11569
11476 PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED; 11570 PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED;
11477 Object* new_array; 11571 Object* new_array;
11478 { MaybeObject* maybe_new_array = 11572 { MaybeObject* maybe_new_array =
11479 heap->AllocateFixedArray(dict->NumberOfElements(), tenure); 11573 heap->AllocateFixedArray(dict->NumberOfElements(), tenure);
11480 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; 11574 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array;
11481 } 11575 }
11482 FixedArray* fast_elements = FixedArray::cast(new_array); 11576 FixedArray* fast_elements = FixedArray::cast(new_array);
11483 dict->CopyValuesTo(fast_elements); 11577 dict->CopyValuesTo(fast_elements);
11578 ValidateElements();
11484 11579
11485 set_map(new_map); 11580 set_map_and_elements(new_map, fast_elements);
11486 set_elements(fast_elements);
11487 } else if (HasExternalArrayElements()) { 11581 } else if (HasExternalArrayElements()) {
11488 // External arrays cannot have holes or undefined elements. 11582 // External arrays cannot have holes or undefined elements.
11489 return Smi::FromInt(ExternalArray::cast(elements())->length()); 11583 return Smi::FromInt(ExternalArray::cast(elements())->length());
11490 } else if (!HasFastDoubleElements()) { 11584 } else if (!HasFastDoubleElements()) {
11491 Object* obj; 11585 Object* obj;
11492 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 11586 { MaybeObject* maybe_obj = EnsureWritableFastElements();
11493 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 11587 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
11494 } 11588 }
11495 } 11589 }
11496 ASSERT(HasFastTypeElements() || HasFastDoubleElements()); 11590 ASSERT(HasFastSmiOrObjectElements() || HasFastDoubleElements());
11497 11591
11498 // Collect holes at the end, undefined before that and the rest at the 11592 // Collect holes at the end, undefined before that and the rest at the
11499 // start, and return the number of non-hole, non-undefined values. 11593 // start, and return the number of non-hole, non-undefined values.
11500 11594
11501 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements()); 11595 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements());
11502 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); 11596 uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
11503 if (limit > elements_length) { 11597 if (limit > elements_length) {
11504 limit = elements_length ; 11598 limit = elements_length ;
11505 } 11599 }
11506 if (limit == 0) { 11600 if (limit == 0) {
(...skipping 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after
13163 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13257 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13164 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13258 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13165 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13259 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13166 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13260 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13167 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13261 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13168 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13262 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13169 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13263 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13170 } 13264 }
13171 13265
13172 } } // namespace v8::internal 13266 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698