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

Side by Side Diff: src/objects.cc

Issue 110573004: Merge bleeding_edge 17696:18016. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 15 matching lines...) Expand all
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "accessors.h" 30 #include "accessors.h"
31 #include "allocation-site-scopes.h" 31 #include "allocation-site-scopes.h"
32 #include "api.h" 32 #include "api.h"
33 #include "arguments.h" 33 #include "arguments.h"
34 #include "bootstrapper.h" 34 #include "bootstrapper.h"
35 #include "codegen.h" 35 #include "codegen.h"
36 #include "code-stubs.h"
36 #include "cpu-profiler.h" 37 #include "cpu-profiler.h"
37 #include "debug.h" 38 #include "debug.h"
38 #include "deoptimizer.h" 39 #include "deoptimizer.h"
39 #include "date.h" 40 #include "date.h"
40 #include "elements.h" 41 #include "elements.h"
41 #include "execution.h" 42 #include "execution.h"
42 #include "full-codegen.h" 43 #include "full-codegen.h"
43 #include "hydrogen.h" 44 #include "hydrogen.h"
44 #include "isolate-inl.h" 45 #include "isolate-inl.h"
45 #include "log.h" 46 #include "log.h"
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 double num = HeapNumber::cast(this)->value(); 197 double num = HeapNumber::cast(this)->value();
197 if (num >= 0 && FastUI2D(FastD2UI(num)) == num) { 198 if (num >= 0 && FastUI2D(FastD2UI(num)) == num) {
198 *value = FastD2UI(num); 199 *value = FastD2UI(num);
199 return true; 200 return true;
200 } 201 }
201 } 202 }
202 return false; 203 return false;
203 } 204 }
204 205
205 206
207 bool FunctionTemplateInfo::IsTemplateFor(Object* object) {
208 if (!object->IsHeapObject()) return false;
209 return IsTemplateFor(HeapObject::cast(object)->map());
210 }
211
212
213 bool FunctionTemplateInfo::IsTemplateFor(Map* map) {
214 // There is a constraint on the object; check.
215 if (!map->IsJSObjectMap()) return false;
216 // Fetch the constructor function of the object.
217 Object* cons_obj = map->constructor();
218 if (!cons_obj->IsJSFunction()) return false;
219 JSFunction* fun = JSFunction::cast(cons_obj);
220 // Iterate through the chain of inheriting function templates to
221 // see if the required one occurs.
222 for (Object* type = fun->shared()->function_data();
223 type->IsFunctionTemplateInfo();
224 type = FunctionTemplateInfo::cast(type)->parent_template()) {
225 if (type == this) return true;
226 }
227 // Didn't find the required type in the inheritance chain.
228 return false;
229 }
230
231
206 template<typename To> 232 template<typename To>
207 static inline To* CheckedCast(void *from) { 233 static inline To* CheckedCast(void *from) {
208 uintptr_t temp = reinterpret_cast<uintptr_t>(from); 234 uintptr_t temp = reinterpret_cast<uintptr_t>(from);
209 ASSERT(temp % sizeof(To) == 0); 235 ASSERT(temp % sizeof(To) == 0);
210 return reinterpret_cast<To*>(temp); 236 return reinterpret_cast<To*>(temp);
211 } 237 }
212 238
213 239
214 static MaybeObject* PerformCompare(const BitmaskCompareDescriptor& descriptor, 240 static MaybeObject* PerformCompare(const BitmaskCompareDescriptor& descriptor,
215 char* ptr, 241 char* ptr,
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
1021 return context->symbol_function()->instance_prototype(); 1047 return context->symbol_function()->instance_prototype();
1022 } 1048 }
1023 if (heap_object->IsBoolean()) { 1049 if (heap_object->IsBoolean()) {
1024 return context->boolean_function()->instance_prototype(); 1050 return context->boolean_function()->instance_prototype();
1025 } else { 1051 } else {
1026 return isolate->heap()->null_value(); 1052 return isolate->heap()->null_value();
1027 } 1053 }
1028 } 1054 }
1029 1055
1030 1056
1057 Map* Object::GetMarkerMap(Isolate* isolate) {
1058 if (IsSmi()) return isolate->heap()->heap_number_map();
1059 return HeapObject::cast(this)->map();
1060 }
1061
1062
1031 Object* Object::GetHash() { 1063 Object* Object::GetHash() {
1032 // The object is either a number, a name, an odd-ball, 1064 // The object is either a number, a name, an odd-ball,
1033 // a real JS object, or a Harmony proxy. 1065 // a real JS object, or a Harmony proxy.
1034 if (IsNumber()) { 1066 if (IsNumber()) {
1035 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); 1067 uint32_t hash = ComputeLongHash(double_to_uint64(Number()));
1036 return Smi::FromInt(hash & Smi::kMaxValue); 1068 return Smi::FromInt(hash & Smi::kMaxValue);
1037 } 1069 }
1038 if (IsName()) { 1070 if (IsName()) {
1039 uint32_t hash = Name::cast(this)->Hash(); 1071 uint32_t hash = Name::cast(this)->Hash();
1040 return Smi::FromInt(hash); 1072 return Smi::FromInt(hash);
(...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after
2124 Handle<Object> args[1] = { name }; 2156 Handle<Object> args[1] = { name };
2125 Handle<Object> error = isolate->factory()->NewTypeError( 2157 Handle<Object> error = isolate->factory()->NewTypeError(
2126 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); 2158 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
2127 isolate->Throw(*error); 2159 isolate->Throw(*error);
2128 return Handle<Object>(); 2160 return Handle<Object>();
2129 } 2161 }
2130 } 2162 }
2131 2163
2132 if (object->HasFastProperties()) { 2164 if (object->HasFastProperties()) {
2133 // Ensure the descriptor array does not get too big. 2165 // Ensure the descriptor array does not get too big.
2134 if (object->map()->NumberOfOwnDescriptors() < 2166 if (object->map()->NumberOfOwnDescriptors() <= kMaxNumberOfDescriptors) {
2135 DescriptorArray::kMaxNumberOfDescriptors) {
2136 // TODO(verwaest): Support other constants. 2167 // TODO(verwaest): Support other constants.
2137 // if (mode == ALLOW_AS_CONSTANT && 2168 // if (mode == ALLOW_AS_CONSTANT &&
2138 // !value->IsTheHole() && 2169 // !value->IsTheHole() &&
2139 // !value->IsConsString()) { 2170 // !value->IsConsString()) {
2140 if (value->IsJSFunction()) { 2171 if (value->IsJSFunction()) {
2141 AddConstantProperty(object, name, value, attributes, transition_flag); 2172 AddConstantProperty(object, name, value, attributes, transition_flag);
2142 } else { 2173 } else {
2143 AddFastProperty(object, name, value, attributes, store_mode, 2174 AddFastProperty(object, name, value, attributes, store_mode,
2144 value_type, transition_flag); 2175 value_type, transition_flag);
2145 } 2176 }
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
2547 transitions->GetTarget(transition)->DeprecateTransitionTree(); 2578 transitions->GetTarget(transition)->DeprecateTransitionTree();
2548 } 2579 }
2549 } 2580 }
2550 2581
2551 // Don't overwrite the empty descriptor array. 2582 // Don't overwrite the empty descriptor array.
2552 if (NumberOfOwnDescriptors() == 0) return; 2583 if (NumberOfOwnDescriptors() == 0) return;
2553 2584
2554 DescriptorArray* to_replace = instance_descriptors(); 2585 DescriptorArray* to_replace = instance_descriptors();
2555 Map* current = this; 2586 Map* current = this;
2556 while (current->instance_descriptors() == to_replace) { 2587 while (current->instance_descriptors() == to_replace) {
2557 current->SetEnumLength(Map::kInvalidEnumCache); 2588 current->SetEnumLength(kInvalidEnumCacheSentinel);
2558 current->set_instance_descriptors(new_descriptors); 2589 current->set_instance_descriptors(new_descriptors);
2559 Object* next = current->GetBackPointer(); 2590 Object* next = current->GetBackPointer();
2560 if (next->IsUndefined()) break; 2591 if (next->IsUndefined()) break;
2561 current = Map::cast(next); 2592 current = Map::cast(next);
2562 } 2593 }
2563 2594
2564 set_owns_descriptors(false); 2595 set_owns_descriptors(false);
2565 } 2596 }
2566 2597
2567 2598
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
2747 stdout, "", modify_index, descriptor, descriptors, 2778 stdout, "", modify_index, descriptor, descriptors,
2748 old_descriptors->GetDetails(modify_index).type() == CONSTANT && 2779 old_descriptors->GetDetails(modify_index).type() == CONSTANT &&
2749 store_mode == FORCE_FIELD, 2780 store_mode == FORCE_FIELD,
2750 old_representation, updated_representation); 2781 old_representation, updated_representation);
2751 } 2782 }
2752 2783
2753 // Add missing transitions. 2784 // Add missing transitions.
2754 Handle<Map> new_map = split_map; 2785 Handle<Map> new_map = split_map;
2755 for (; descriptor < descriptors; descriptor++) { 2786 for (; descriptor < descriptors; descriptor++) {
2756 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); 2787 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors);
2757 new_map->set_migration_target(true);
2758 } 2788 }
2759 2789
2760 new_map->set_owns_descriptors(true); 2790 new_map->set_owns_descriptors(true);
2761 return new_map; 2791 return new_map;
2762 } 2792 }
2763 2793
2764 2794
2765 // Generalize the representation of all FIELD descriptors. 2795 // Generalize the representation of all FIELD descriptors.
2766 Handle<Map> Map::GeneralizeAllFieldRepresentations( 2796 Handle<Map> Map::GeneralizeAllFieldRepresentations(
2767 Handle<Map> map, 2797 Handle<Map> map,
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2959 bool has_pending_exception; 2989 bool has_pending_exception;
2960 Handle<Object> argv[] = { value }; 2990 Handle<Object> argv[] = { value };
2961 Execution::Call( 2991 Execution::Call(
2962 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); 2992 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception);
2963 // Check for pending exception and return the result. 2993 // Check for pending exception and return the result.
2964 if (has_pending_exception) return Handle<Object>(); 2994 if (has_pending_exception) return Handle<Object>();
2965 return value; 2995 return value;
2966 } 2996 }
2967 2997
2968 2998
2969 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( 2999 Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes(
3000 Handle<JSObject> object,
2970 uint32_t index, 3001 uint32_t index,
2971 Object* value, 3002 Handle<Object> value,
2972 bool* found, 3003 bool* found,
2973 StrictModeFlag strict_mode) { 3004 StrictModeFlag strict_mode) {
2974 Heap* heap = GetHeap(); 3005 Isolate *isolate = object->GetIsolate();
2975 for (Object* pt = GetPrototype(); 3006 for (Handle<Object> proto = handle(object->GetPrototype(), isolate);
2976 pt != heap->null_value(); 3007 !proto->IsNull();
2977 pt = pt->GetPrototype(GetIsolate())) { 3008 proto = handle(proto->GetPrototype(isolate), isolate)) {
2978 if (pt->IsJSProxy()) { 3009 if (proto->IsJSProxy()) {
2979 Isolate* isolate = GetIsolate(); 3010 return JSProxy::SetPropertyViaPrototypesWithHandler(
2980 HandleScope scope(isolate); 3011 Handle<JSProxy>::cast(proto),
2981 Handle<JSProxy> proxy(JSProxy::cast(pt)); 3012 object,
2982 Handle<JSObject> self(this, isolate); 3013 isolate->factory()->Uint32ToString(index), // name
2983 Handle<String> name = isolate->factory()->Uint32ToString(index); 3014 value,
2984 Handle<Object> value_handle(value, isolate); 3015 NONE,
2985 Handle<Object> result = JSProxy::SetPropertyViaPrototypesWithHandler( 3016 strict_mode,
2986 proxy, self, name, value_handle, NONE, strict_mode, found); 3017 found);
2987 RETURN_IF_EMPTY_HANDLE(isolate, result);
2988 return *result;
2989 } 3018 }
2990 if (!JSObject::cast(pt)->HasDictionaryElements()) { 3019 Handle<JSObject> js_proto = Handle<JSObject>::cast(proto);
3020 if (!js_proto->HasDictionaryElements()) {
2991 continue; 3021 continue;
2992 } 3022 }
2993 SeededNumberDictionary* dictionary = 3023 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary());
2994 JSObject::cast(pt)->element_dictionary();
2995 int entry = dictionary->FindEntry(index); 3024 int entry = dictionary->FindEntry(index);
2996 if (entry != SeededNumberDictionary::kNotFound) { 3025 if (entry != SeededNumberDictionary::kNotFound) {
2997 PropertyDetails details = dictionary->DetailsAt(entry); 3026 PropertyDetails details = dictionary->DetailsAt(entry);
2998 if (details.type() == CALLBACKS) { 3027 if (details.type() == CALLBACKS) {
2999 *found = true; 3028 *found = true;
3000 Isolate* isolate = GetIsolate();
3001 HandleScope scope(isolate);
3002 Handle<JSObject> self(this, isolate);
3003 Handle<Object> structure(dictionary->ValueAt(entry), isolate); 3029 Handle<Object> structure(dictionary->ValueAt(entry), isolate);
3004 Handle<Object> value_handle(value, isolate); 3030 return SetElementWithCallback(object, structure, index, value, js_proto,
3005 Handle<JSObject> holder(JSObject::cast(pt)); 3031 strict_mode);
3006 Handle<Object> result = SetElementWithCallback(
3007 self, structure, index, value_handle, holder, strict_mode);
3008 RETURN_IF_EMPTY_HANDLE(isolate, result);
3009 return *result;
3010 } 3032 }
3011 } 3033 }
3012 } 3034 }
3013 *found = false; 3035 *found = false;
3014 return heap->the_hole_value(); 3036 return isolate->factory()->the_hole_value();
3015 } 3037 }
3016 3038
3017 3039
3018 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, 3040 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
3019 Handle<Name> name, 3041 Handle<Name> name,
3020 Handle<Object> value, 3042 Handle<Object> value,
3021 PropertyAttributes attributes, 3043 PropertyAttributes attributes,
3022 StrictModeFlag strict_mode, 3044 StrictModeFlag strict_mode,
3023 bool* done) { 3045 bool* done) {
3024 Isolate* isolate = object->GetIsolate(); 3046 Isolate* isolate = object->GetIsolate();
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after
3846 } 3868 }
3847 3869
3848 3870
3849 void JSObject::MigrateInstance(Handle<JSObject> object) { 3871 void JSObject::MigrateInstance(Handle<JSObject> object) {
3850 // Converting any field to the most specific type will cause the 3872 // Converting any field to the most specific type will cause the
3851 // GeneralizeFieldRepresentation algorithm to create the most general existing 3873 // GeneralizeFieldRepresentation algorithm to create the most general existing
3852 // transition that matches the object. This achieves what is needed. 3874 // transition that matches the object. This achieves what is needed.
3853 Handle<Map> original_map(object->map()); 3875 Handle<Map> original_map(object->map());
3854 GeneralizeFieldRepresentation( 3876 GeneralizeFieldRepresentation(
3855 object, 0, Representation::None(), ALLOW_AS_CONSTANT); 3877 object, 0, Representation::None(), ALLOW_AS_CONSTANT);
3878 object->map()->set_migration_target(true);
3856 if (FLAG_trace_migration) { 3879 if (FLAG_trace_migration) {
3857 object->PrintInstanceMigration(stdout, *original_map, object->map()); 3880 object->PrintInstanceMigration(stdout, *original_map, object->map());
3858 } 3881 }
3859 } 3882 }
3860 3883
3861 3884
3862 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { 3885 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
3863 Map* new_map = object->map()->CurrentMapForDeprecated(); 3886 Map* new_map = object->map()->CurrentMapForDeprecated();
3864 if (new_map == NULL) return Handle<Object>(); 3887 if (new_map == NULL) return Handle<Object>();
3865 Handle<Map> original_map(object->map()); 3888 Handle<Map> original_map(object->map());
(...skipping 1741 matching lines...) Expand 10 before | Expand all | Expand 10 after
5607 return object; 5630 return object;
5608 } 5631 }
5609 5632
5610 5633
5611 void JSObject::SetObserved(Handle<JSObject> object) { 5634 void JSObject::SetObserved(Handle<JSObject> object) {
5612 Isolate* isolate = object->GetIsolate(); 5635 Isolate* isolate = object->GetIsolate();
5613 5636
5614 if (object->map()->is_observed()) 5637 if (object->map()->is_observed())
5615 return; 5638 return;
5616 5639
5617 if (!object->HasExternalArrayElements()) {
5618 // Go to dictionary mode, so that we don't skip map checks.
5619 NormalizeElements(object);
5620 ASSERT(!object->HasFastElements());
5621 }
5622
5623 LookupResult result(isolate); 5640 LookupResult result(isolate);
5624 object->map()->LookupTransition(*object, 5641 object->map()->LookupTransition(*object,
5625 isolate->heap()->observed_symbol(), 5642 isolate->heap()->observed_symbol(),
5626 &result); 5643 &result);
5627 5644
5628 Handle<Map> new_map; 5645 Handle<Map> new_map;
5629 if (result.IsTransition()) { 5646 if (result.IsTransition()) {
5630 new_map = handle(result.GetTransitionTarget()); 5647 new_map = handle(result.GetTransitionTarget());
5631 ASSERT(new_map->is_observed()); 5648 ASSERT(new_map->is_observed());
5632 } else if (object->map()->CanHaveMoreTransitions()) { 5649 } else if (object->map()->CanHaveMoreTransitions()) {
5633 new_map = Map::CopyForObserved(handle(object->map())); 5650 new_map = Map::CopyForObserved(handle(object->map()));
5634 } else { 5651 } else {
5635 new_map = Map::Copy(handle(object->map())); 5652 new_map = Map::Copy(handle(object->map()));
5636 new_map->set_is_observed(true); 5653 new_map->set_is_observed();
5637 } 5654 }
5638 object->set_map(*new_map); 5655 object->set_map(*new_map);
5639 } 5656 }
5640 5657
5641 5658
5642 Handle<JSObject> JSObject::Copy(Handle<JSObject> object, 5659 Handle<JSObject> JSObject::Copy(Handle<JSObject> object,
5643 Handle<AllocationSite> site) { 5660 Handle<AllocationSite> site) {
5644 Isolate* isolate = object->GetIsolate(); 5661 Isolate* isolate = object->GetIsolate();
5645 CALL_HEAP_FUNCTION(isolate, 5662 CALL_HEAP_FUNCTION(isolate,
5646 isolate->heap()->CopyJSObject(*object, *site), JSObject); 5663 isolate->heap()->CopyJSObject(*object, *site), JSObject);
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
5916 // - This object has no elements. 5933 // - This object has no elements.
5917 // - No prototype has enumerable properties/elements. 5934 // - No prototype has enumerable properties/elements.
5918 bool JSReceiver::IsSimpleEnum() { 5935 bool JSReceiver::IsSimpleEnum() {
5919 Heap* heap = GetHeap(); 5936 Heap* heap = GetHeap();
5920 for (Object* o = this; 5937 for (Object* o = this;
5921 o != heap->null_value(); 5938 o != heap->null_value();
5922 o = JSObject::cast(o)->GetPrototype()) { 5939 o = JSObject::cast(o)->GetPrototype()) {
5923 if (!o->IsJSObject()) return false; 5940 if (!o->IsJSObject()) return false;
5924 JSObject* curr = JSObject::cast(o); 5941 JSObject* curr = JSObject::cast(o);
5925 int enum_length = curr->map()->EnumLength(); 5942 int enum_length = curr->map()->EnumLength();
5926 if (enum_length == Map::kInvalidEnumCache) return false; 5943 if (enum_length == kInvalidEnumCacheSentinel) return false;
5927 ASSERT(!curr->HasNamedInterceptor()); 5944 ASSERT(!curr->HasNamedInterceptor());
5928 ASSERT(!curr->HasIndexedInterceptor()); 5945 ASSERT(!curr->HasIndexedInterceptor());
5929 ASSERT(!curr->IsAccessCheckNeeded()); 5946 ASSERT(!curr->IsAccessCheckNeeded());
5930 if (curr->NumberOfEnumElements() > 0) return false; 5947 if (curr->NumberOfEnumElements() > 0) return false;
5931 if (curr != this && enum_length != 0) return false; 5948 if (curr != this && enum_length != 0) return false;
5932 } 5949 }
5933 return true; 5950 return true;
5934 } 5951 }
5935 5952
5936 5953
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
6170 Handle<Name> name, 6187 Handle<Name> name,
6171 Handle<Object> getter, 6188 Handle<Object> getter,
6172 Handle<Object> setter, 6189 Handle<Object> setter,
6173 PropertyAttributes attributes, 6190 PropertyAttributes attributes,
6174 v8::AccessControl access_control) { 6191 v8::AccessControl access_control) {
6175 // We could assert that the property is configurable here, but we would need 6192 // We could assert that the property is configurable here, but we would need
6176 // to do a lookup, which seems to be a bit of overkill. 6193 // to do a lookup, which seems to be a bit of overkill.
6177 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); 6194 bool only_attribute_changes = getter->IsNull() && setter->IsNull();
6178 if (object->HasFastProperties() && !only_attribute_changes && 6195 if (object->HasFastProperties() && !only_attribute_changes &&
6179 access_control == v8::DEFAULT && 6196 access_control == v8::DEFAULT &&
6180 (object->map()->NumberOfOwnDescriptors() < 6197 (object->map()->NumberOfOwnDescriptors() <= kMaxNumberOfDescriptors)) {
6181 DescriptorArray::kMaxNumberOfDescriptors)) {
6182 bool getterOk = getter->IsNull() || 6198 bool getterOk = getter->IsNull() ||
6183 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); 6199 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes);
6184 bool setterOk = !getterOk || setter->IsNull() || 6200 bool setterOk = !getterOk || setter->IsNull() ||
6185 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); 6201 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes);
6186 if (getterOk && setterOk) return; 6202 if (getterOk && setterOk) return;
6187 } 6203 }
6188 6204
6189 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); 6205 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name);
6190 accessors->SetComponents(*getter, *setter); 6206 accessors->SetComponents(*getter, *setter);
6191 accessors->set_access_flags(access_control); 6207 accessors->set_access_flags(access_control);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
6249 Handle<Object> structure, 6265 Handle<Object> structure,
6250 PropertyAttributes attributes) { 6266 PropertyAttributes attributes) {
6251 Heap* heap = object->GetHeap(); 6267 Heap* heap = object->GetHeap();
6252 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); 6268 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
6253 6269
6254 // Normalize elements to make this operation simple. 6270 // Normalize elements to make this operation simple.
6255 bool had_dictionary_elements = object->HasDictionaryElements(); 6271 bool had_dictionary_elements = object->HasDictionaryElements();
6256 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 6272 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
6257 ASSERT(object->HasDictionaryElements() || 6273 ASSERT(object->HasDictionaryElements() ||
6258 object->HasDictionaryArgumentsElements()); 6274 object->HasDictionaryArgumentsElements());
6259
6260 // Update the dictionary with the new CALLBACKS property. 6275 // Update the dictionary with the new CALLBACKS property.
6261 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, 6276 dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
6262 details); 6277 details);
6263 dictionary->set_requires_slow_elements(); 6278 dictionary->set_requires_slow_elements();
6264 6279
6265 // Update the dictionary backing store on the object. 6280 // Update the dictionary backing store on the object.
6266 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { 6281 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) {
6267 // Also delete any parameter alias. 6282 // Also delete any parameter alias.
6268 // 6283 //
6269 // TODO(kmillikin): when deleting the last parameter alias we could 6284 // TODO(kmillikin): when deleting the last parameter alias we could
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
6689 GetHeap()->AllocateMap(instance_type(), instance_size); 6704 GetHeap()->AllocateMap(instance_type(), instance_size);
6690 if (!maybe_result->To(&result)) return maybe_result; 6705 if (!maybe_result->To(&result)) return maybe_result;
6691 6706
6692 result->set_prototype(prototype()); 6707 result->set_prototype(prototype());
6693 result->set_constructor(constructor()); 6708 result->set_constructor(constructor());
6694 result->set_bit_field(bit_field()); 6709 result->set_bit_field(bit_field());
6695 result->set_bit_field2(bit_field2()); 6710 result->set_bit_field2(bit_field2());
6696 int new_bit_field3 = bit_field3(); 6711 int new_bit_field3 = bit_field3();
6697 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); 6712 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true);
6698 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); 6713 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0);
6699 new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache); 6714 new_bit_field3 = EnumLengthBits::update(new_bit_field3,
6715 kInvalidEnumCacheSentinel);
6700 new_bit_field3 = Deprecated::update(new_bit_field3, false); 6716 new_bit_field3 = Deprecated::update(new_bit_field3, false);
6701 new_bit_field3 = IsUnstable::update(new_bit_field3, false); 6717 new_bit_field3 = IsUnstable::update(new_bit_field3, false);
6702 result->set_bit_field3(new_bit_field3); 6718 result->set_bit_field3(new_bit_field3);
6703 return result; 6719 return result;
6704 } 6720 }
6705 6721
6706 6722
6707 Handle<Map> Map::CopyNormalized(Handle<Map> map, 6723 Handle<Map> Map::CopyNormalized(Handle<Map> map,
6708 PropertyNormalizationMode mode, 6724 PropertyNormalizationMode mode,
6709 NormalizedMapSharingMode sharing) { 6725 NormalizedMapSharingMode sharing) {
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
6964 } else { 6980 } else {
6965 new_map = Map::Copy(map); 6981 new_map = Map::Copy(map);
6966 } 6982 }
6967 6983
6968 Handle<TransitionArray> transitions = 6984 Handle<TransitionArray> transitions =
6969 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map, 6985 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map,
6970 FULL_TRANSITION); 6986 FULL_TRANSITION);
6971 6987
6972 map->set_transitions(*transitions); 6988 map->set_transitions(*transitions);
6973 6989
6974 new_map->set_is_observed(true); 6990 new_map->set_is_observed();
6975 6991
6976 if (map->owns_descriptors()) { 6992 if (map->owns_descriptors()) {
6977 new_map->InitializeDescriptors(map->instance_descriptors()); 6993 new_map->InitializeDescriptors(map->instance_descriptors());
6978 map->set_owns_descriptors(false); 6994 map->set_owns_descriptors(false);
6979 } 6995 }
6980 6996
6981 new_map->SetBackPointer(*map); 6997 new_map->SetBackPointer(*map);
6982 return new_map; 6998 return new_map;
6983 } 6999 }
6984 7000
(...skipping 2332 matching lines...) Expand 10 before | Expand all | Expand 10 after
9317 void String::PrintOn(FILE* file) { 9333 void String::PrintOn(FILE* file) {
9318 int length = this->length(); 9334 int length = this->length();
9319 for (int i = 0; i < length; i++) { 9335 for (int i = 0; i < length; i++) {
9320 PrintF(file, "%c", Get(i)); 9336 PrintF(file, "%c", Get(i));
9321 } 9337 }
9322 } 9338 }
9323 9339
9324 9340
9325 static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) { 9341 static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) {
9326 int live_enum = map->EnumLength(); 9342 int live_enum = map->EnumLength();
9327 if (live_enum == Map::kInvalidEnumCache) { 9343 if (live_enum == kInvalidEnumCacheSentinel) {
9328 live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM); 9344 live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
9329 } 9345 }
9330 if (live_enum == 0) return descriptors->ClearEnumCache(); 9346 if (live_enum == 0) return descriptors->ClearEnumCache();
9331 9347
9332 FixedArray* enum_cache = descriptors->GetEnumCache(); 9348 FixedArray* enum_cache = descriptors->GetEnumCache();
9333 9349
9334 int to_trim = enum_cache->length() - live_enum; 9350 int to_trim = enum_cache->length() - live_enum;
9335 if (to_trim <= 0) return; 9351 if (to_trim <= 0) return;
9336 RightTrimFixedArray<FROM_GC>(heap, descriptors->GetEnumCache(), to_trim); 9352 RightTrimFixedArray<FROM_GC>(heap, descriptors->GetEnumCache(), to_trim);
9337 9353
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
9501 GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile)); 9517 GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile));
9502 // No write barrier required, since the builtin is part of the root set. 9518 // No write barrier required, since the builtin is part of the root set.
9503 } 9519 }
9504 9520
9505 9521
9506 void JSFunction::MarkForConcurrentRecompilation() { 9522 void JSFunction::MarkForConcurrentRecompilation() {
9507 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); 9523 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints());
9508 ASSERT(!IsOptimized()); 9524 ASSERT(!IsOptimized());
9509 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); 9525 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
9510 ASSERT(!shared()->is_generator()); 9526 ASSERT(!shared()->is_generator());
9511 ASSERT(FLAG_concurrent_recompilation); 9527 ASSERT(GetIsolate()->concurrent_recompilation_enabled());
9512 if (FLAG_trace_concurrent_recompilation) { 9528 if (FLAG_trace_concurrent_recompilation) {
9513 PrintF(" ** Marking "); 9529 PrintF(" ** Marking ");
9514 PrintName(); 9530 PrintName();
9515 PrintF(" for concurrent recompilation.\n"); 9531 PrintF(" for concurrent recompilation.\n");
9516 } 9532 }
9517 set_code_no_write_barrier( 9533 set_code_no_write_barrier(
9518 GetIsolate()->builtins()->builtin(Builtins::kConcurrentRecompile)); 9534 GetIsolate()->builtins()->builtin(Builtins::kConcurrentRecompile));
9519 // No write barrier required, since the builtin is part of the root set. 9535 // No write barrier required, since the builtin is part of the root set.
9520 } 9536 }
9521 9537
9522 9538
9523 void JSFunction::MarkInRecompileQueue() { 9539 void JSFunction::MarkInRecompileQueue() {
9524 // We can only arrive here via the concurrent-recompilation builtin. If 9540 // We can only arrive here via the concurrent-recompilation builtin. If
9525 // break points were set, the code would point to the lazy-compile builtin. 9541 // break points were set, the code would point to the lazy-compile builtin.
9526 ASSERT(!GetIsolate()->DebuggerHasBreakPoints()); 9542 ASSERT(!GetIsolate()->DebuggerHasBreakPoints());
9527 ASSERT(IsMarkedForConcurrentRecompilation() && !IsOptimized()); 9543 ASSERT(IsMarkedForConcurrentRecompilation() && !IsOptimized());
9528 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); 9544 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
9529 ASSERT(FLAG_concurrent_recompilation); 9545 ASSERT(GetIsolate()->concurrent_recompilation_enabled());
9530 if (FLAG_trace_concurrent_recompilation) { 9546 if (FLAG_trace_concurrent_recompilation) {
9531 PrintF(" ** Queueing "); 9547 PrintF(" ** Queueing ");
9532 PrintName(); 9548 PrintName();
9533 PrintF(" for concurrent recompilation.\n"); 9549 PrintF(" for concurrent recompilation.\n");
9534 } 9550 }
9535 set_code_no_write_barrier( 9551 set_code_no_write_barrier(
9536 GetIsolate()->builtins()->builtin(Builtins::kInRecompileQueue)); 9552 GetIsolate()->builtins()->builtin(Builtins::kInRecompileQueue));
9537 // No write barrier required, since the builtin is part of the root set. 9553 // No write barrier required, since the builtin is part of the root set.
9538 } 9554 }
9539 9555
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
10379 Address p = rinfo->target_reference(); 10395 Address p = rinfo->target_reference();
10380 VisitExternalReference(&p); 10396 VisitExternalReference(&p);
10381 } 10397 }
10382 10398
10383 10399
10384 void Code::InvalidateRelocation() { 10400 void Code::InvalidateRelocation() {
10385 set_relocation_info(GetHeap()->empty_byte_array()); 10401 set_relocation_info(GetHeap()->empty_byte_array());
10386 } 10402 }
10387 10403
10388 10404
10405 void Code::InvalidateEmbeddedObjects() {
10406 Object* undefined = GetHeap()->undefined_value();
10407 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
10408 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) {
10409 RelocInfo::Mode mode = it.rinfo()->rmode();
10410 if (mode == RelocInfo::EMBEDDED_OBJECT) {
10411 it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER);
10412 }
10413 }
10414 }
10415
10416
10389 void Code::Relocate(intptr_t delta) { 10417 void Code::Relocate(intptr_t delta) {
10390 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { 10418 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) {
10391 it.rinfo()->apply(delta); 10419 it.rinfo()->apply(delta);
10392 } 10420 }
10393 CPU::FlushICache(instruction_start(), instruction_size()); 10421 CPU::FlushICache(instruction_start(), instruction_size());
10394 } 10422 }
10395 10423
10396 10424
10397 void Code::CopyFrom(const CodeDesc& desc) { 10425 void Code::CopyFrom(const CodeDesc& desc) {
10398 ASSERT(Marking::Color(this) == Marking::WHITE_OBJECT); 10426 ASSERT(Marking::Color(this) == Marking::WHITE_OBJECT);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
10553 } 10581 }
10554 10582
10555 10583
10556 void Code::FindAllMaps(MapHandleList* maps) { 10584 void Code::FindAllMaps(MapHandleList* maps) {
10557 ASSERT(is_inline_cache_stub()); 10585 ASSERT(is_inline_cache_stub());
10558 DisallowHeapAllocation no_allocation; 10586 DisallowHeapAllocation no_allocation;
10559 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 10587 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
10560 for (RelocIterator it(this, mask); !it.done(); it.next()) { 10588 for (RelocIterator it(this, mask); !it.done(); it.next()) {
10561 RelocInfo* info = it.rinfo(); 10589 RelocInfo* info = it.rinfo();
10562 Object* object = info->target_object(); 10590 Object* object = info->target_object();
10563 if (object->IsMap()) maps->Add(Handle<Map>(Map::cast(object))); 10591 if (object->IsMap()) maps->Add(handle(Map::cast(object)));
10564 } 10592 }
10565 } 10593 }
10566 10594
10595
10596 void Code::FindAllTypes(TypeHandleList* types) {
10597 ASSERT(is_inline_cache_stub());
10598 DisallowHeapAllocation no_allocation;
10599 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
10600 Isolate* isolate = GetIsolate();
10601 for (RelocIterator it(this, mask); !it.done(); it.next()) {
10602 RelocInfo* info = it.rinfo();
10603 Object* object = info->target_object();
10604 if (object->IsMap()) {
10605 Handle<Map> map(Map::cast(object));
10606 types->Add(handle(IC::MapToType(map), isolate));
10607 }
10608 }
10609 }
10610
10567 10611
10568 void Code::ReplaceFirstMap(Map* replace_with) { 10612 void Code::ReplaceFirstMap(Map* replace_with) {
10569 ReplaceNthObject(1, GetHeap()->meta_map(), replace_with); 10613 ReplaceNthObject(1, GetHeap()->meta_map(), replace_with);
10570 } 10614 }
10571 10615
10572 10616
10573 Code* Code::FindFirstHandler() { 10617 Code* Code::FindFirstHandler() {
10574 ASSERT(is_inline_cache_stub()); 10618 ASSERT(is_inline_cache_stub());
10575 DisallowHeapAllocation no_allocation; 10619 DisallowHeapAllocation no_allocation;
10576 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); 10620 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after
11062 case DEBUG_STUB: return "DEBUG_STUB"; 11106 case DEBUG_STUB: return "DEBUG_STUB";
11063 } 11107 }
11064 UNREACHABLE(); 11108 UNREACHABLE();
11065 return NULL; 11109 return NULL;
11066 } 11110 }
11067 11111
11068 11112
11069 const char* Code::StubType2String(StubType type) { 11113 const char* Code::StubType2String(StubType type) {
11070 switch (type) { 11114 switch (type) {
11071 case NORMAL: return "NORMAL"; 11115 case NORMAL: return "NORMAL";
11072 case FIELD: return "FIELD"; 11116 case FAST: return "FAST";
11073 case CONSTANT: return "CONSTANT";
11074 case CALLBACKS: return "CALLBACKS";
11075 case INTERCEPTOR: return "INTERCEPTOR";
11076 case TRANSITION: return "TRANSITION";
11077 case NONEXISTENT: return "NONEXISTENT";
11078 } 11117 }
11079 UNREACHABLE(); // keep the compiler happy 11118 UNREACHABLE(); // keep the compiler happy
11080 return NULL; 11119 return NULL;
11081 } 11120 }
11082 11121
11083 11122
11084 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { 11123 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) {
11085 PrintF(out, "extra_ic_state = "); 11124 PrintF(out, "extra_ic_state = ");
11086 const char* name = NULL; 11125 const char* name = NULL;
11087 switch (kind) { 11126 switch (kind) {
(...skipping 14 matching lines...) Expand all
11102 if (name != NULL) { 11141 if (name != NULL) {
11103 PrintF(out, "%s\n", name); 11142 PrintF(out, "%s\n", name);
11104 } else { 11143 } else {
11105 PrintF(out, "%d\n", extra); 11144 PrintF(out, "%d\n", extra);
11106 } 11145 }
11107 } 11146 }
11108 11147
11109 11148
11110 void Code::Disassemble(const char* name, FILE* out) { 11149 void Code::Disassemble(const char* name, FILE* out) {
11111 PrintF(out, "kind = %s\n", Kind2String(kind())); 11150 PrintF(out, "kind = %s\n", Kind2String(kind()));
11151 if (has_major_key()) {
11152 PrintF(out, "major_key = %s\n",
11153 CodeStub::MajorName(CodeStub::GetMajorKey(this), true));
11154 }
11112 if (is_inline_cache_stub()) { 11155 if (is_inline_cache_stub()) {
11113 PrintF(out, "ic_state = %s\n", ICState2String(ic_state())); 11156 PrintF(out, "ic_state = %s\n", ICState2String(ic_state()));
11114 PrintExtraICState(out, kind(), needs_extended_extra_ic_state(kind()) ? 11157 PrintExtraICState(out, kind(), needs_extended_extra_ic_state(kind()) ?
11115 extended_extra_ic_state() : extra_ic_state()); 11158 extended_extra_ic_state() : extra_ic_state());
11116 if (ic_state() == MONOMORPHIC) { 11159 if (ic_state() == MONOMORPHIC) {
11117 PrintF(out, "type = %s\n", StubType2String(type())); 11160 PrintF(out, "type = %s\n", StubType2String(type()));
11118 } 11161 }
11119 if (is_call_stub() || is_keyed_call_stub()) { 11162 if (is_call_stub() || is_keyed_call_stub()) {
11120 PrintF(out, "argc = %d\n", arguments_count()); 11163 PrintF(out, "argc = %d\n", arguments_count());
11121 } 11164 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
11203 11246
11204 PrintF(out, "RelocInfo (size = %d)\n", relocation_size()); 11247 PrintF(out, "RelocInfo (size = %d)\n", relocation_size());
11205 for (RelocIterator it(this); !it.done(); it.next()) { 11248 for (RelocIterator it(this); !it.done(); it.next()) {
11206 it.rinfo()->Print(GetIsolate(), out); 11249 it.rinfo()->Print(GetIsolate(), out);
11207 } 11250 }
11208 PrintF(out, "\n"); 11251 PrintF(out, "\n");
11209 } 11252 }
11210 #endif // ENABLE_DISASSEMBLER 11253 #endif // ENABLE_DISASSEMBLER
11211 11254
11212 11255
11256 Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength(
11257 Handle<JSObject> object,
11258 int capacity,
11259 int length,
11260 SetFastElementsCapacitySmiMode smi_mode) {
11261 CALL_HEAP_FUNCTION(
11262 object->GetIsolate(),
11263 object->SetFastElementsCapacityAndLength(capacity, length, smi_mode),
11264 FixedArray);
11265 }
11266
11267
11213 MaybeObject* JSObject::SetFastElementsCapacityAndLength( 11268 MaybeObject* JSObject::SetFastElementsCapacityAndLength(
11214 int capacity, 11269 int capacity,
11215 int length, 11270 int length,
11216 SetFastElementsCapacitySmiMode smi_mode) { 11271 SetFastElementsCapacitySmiMode smi_mode) {
11217 Heap* heap = GetHeap(); 11272 Heap* heap = GetHeap();
11218 // We should never end in here with a pixel or external array. 11273 // We should never end in here with a pixel or external array.
11219 ASSERT(!HasExternalArrayElements()); 11274 ASSERT(!HasExternalArrayElements());
11220 ASSERT(!map()->is_observed());
11221 11275
11222 // Allocate a new fast elements backing store. 11276 // Allocate a new fast elements backing store.
11223 FixedArray* new_elements; 11277 FixedArray* new_elements;
11224 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); 11278 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity);
11225 if (!maybe->To(&new_elements)) return maybe; 11279 if (!maybe->To(&new_elements)) return maybe;
11226 11280
11227 ElementsKind elements_kind = GetElementsKind(); 11281 ElementsKind elements_kind = GetElementsKind();
11228 ElementsKind new_elements_kind; 11282 ElementsKind new_elements_kind;
11229 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, 11283 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it,
11230 // or if it's allowed and the old elements array contained only SMIs. 11284 // or if it's allowed and the old elements array contained only SMIs.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
11289 FLAG_weak_embedded_maps_in_optimized_code; 11343 FLAG_weak_embedded_maps_in_optimized_code;
11290 } 11344 }
11291 11345
11292 if (object->IsJSObject()) { 11346 if (object->IsJSObject()) {
11293 return FLAG_weak_embedded_objects_in_optimized_code; 11347 return FLAG_weak_embedded_objects_in_optimized_code;
11294 } 11348 }
11295 11349
11296 return false; 11350 return false;
11297 } 11351 }
11298 11352
11353
11354 void JSObject::SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object,
11355 int capacity,
11356 int length) {
11357 CALL_HEAP_FUNCTION_VOID(
11358 object->GetIsolate(),
11359 object->SetFastDoubleElementsCapacityAndLength(capacity, length));
11360 }
11361
11362
11299 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( 11363 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
11300 int capacity, 11364 int capacity,
11301 int length) { 11365 int length) {
11302 Heap* heap = GetHeap(); 11366 Heap* heap = GetHeap();
11303 // We should never end in here with a pixel or external array. 11367 // We should never end in here with a pixel or external array.
11304 ASSERT(!HasExternalArrayElements()); 11368 ASSERT(!HasExternalArrayElements());
11305 ASSERT(!map()->is_observed());
11306 11369
11307 FixedArrayBase* elems; 11370 FixedArrayBase* elems;
11308 { MaybeObject* maybe_obj = 11371 { MaybeObject* maybe_obj =
11309 heap->AllocateUninitializedFixedDoubleArray(capacity); 11372 heap->AllocateUninitializedFixedDoubleArray(capacity);
11310 if (!maybe_obj->To(&elems)) return maybe_obj; 11373 if (!maybe_obj->To(&elems)) return maybe_obj;
11311 } 11374 }
11312 11375
11313 ElementsKind elements_kind = GetElementsKind(); 11376 ElementsKind elements_kind = GetElementsKind();
11314 ElementsKind new_elements_kind = elements_kind; 11377 ElementsKind new_elements_kind = elements_kind;
11315 if (IsHoleyElementsKind(elements_kind)) { 11378 if (IsHoleyElementsKind(elements_kind)) {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
11444 List<uint32_t> indices; 11507 List<uint32_t> indices;
11445 List<Handle<Object> > old_values; 11508 List<Handle<Object> > old_values;
11446 Handle<Object> old_length_handle(self->length(), isolate); 11509 Handle<Object> old_length_handle(self->length(), isolate);
11447 Handle<Object> new_length_handle(len, isolate); 11510 Handle<Object> new_length_handle(len, isolate);
11448 uint32_t old_length = 0; 11511 uint32_t old_length = 0;
11449 CHECK(old_length_handle->ToArrayIndex(&old_length)); 11512 CHECK(old_length_handle->ToArrayIndex(&old_length));
11450 uint32_t new_length = 0; 11513 uint32_t new_length = 0;
11451 if (!new_length_handle->ToArrayIndex(&new_length)) 11514 if (!new_length_handle->ToArrayIndex(&new_length))
11452 return Failure::InternalError(); 11515 return Failure::InternalError();
11453 11516
11454 // Observed arrays should always be in dictionary mode;
11455 // if they were in fast mode, the below is slower than necessary
11456 // as it iterates over the array backing store multiple times.
11457 ASSERT(self->HasDictionaryElements());
11458 static const PropertyAttributes kNoAttrFilter = NONE; 11517 static const PropertyAttributes kNoAttrFilter = NONE;
11459 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); 11518 int num_elements = self->NumberOfLocalElements(kNoAttrFilter);
11460 if (num_elements > 0) { 11519 if (num_elements > 0) {
11461 if (old_length == static_cast<uint32_t>(num_elements)) { 11520 if (old_length == static_cast<uint32_t>(num_elements)) {
11462 // Simple case for arrays without holes. 11521 // Simple case for arrays without holes.
11463 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { 11522 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) {
11464 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; 11523 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break;
11465 } 11524 }
11466 } else { 11525 } else {
11467 // For sparse arrays, only iterate over existing elements. 11526 // For sparse arrays, only iterate over existing elements.
11527 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over
11528 // the to-be-removed indices twice.
11468 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); 11529 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements);
11469 self->GetLocalElementKeys(*keys, kNoAttrFilter); 11530 self->GetLocalElementKeys(*keys, kNoAttrFilter);
11470 while (num_elements-- > 0) { 11531 while (num_elements-- > 0) {
11471 uint32_t index = NumberToUint32(keys->get(num_elements)); 11532 uint32_t index = NumberToUint32(keys->get(num_elements));
11472 if (index < new_length) break; 11533 if (index < new_length) break;
11473 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; 11534 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break;
11474 } 11535 }
11475 } 11536 }
11476 } 11537 }
11477 11538
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
11626 start_indexes_[g] = start_indexes_[g - 1] + count; 11687 start_indexes_[g] = start_indexes_[g - 1] + count;
11627 } 11688 }
11628 } 11689 }
11629 11690
11630 11691
11631 DependentCode* DependentCode::ForObject(Handle<HeapObject> object, 11692 DependentCode* DependentCode::ForObject(Handle<HeapObject> object,
11632 DependencyGroup group) { 11693 DependencyGroup group) {
11633 AllowDeferredHandleDereference dependencies_are_safe; 11694 AllowDeferredHandleDereference dependencies_are_safe;
11634 if (group == DependentCode::kPropertyCellChangedGroup) { 11695 if (group == DependentCode::kPropertyCellChangedGroup) {
11635 return Handle<PropertyCell>::cast(object)->dependent_code(); 11696 return Handle<PropertyCell>::cast(object)->dependent_code();
11697 } else if (group == DependentCode::kAllocationSiteTenuringChangedGroup ||
11698 group == DependentCode::kAllocationSiteTransitionChangedGroup) {
11699 return Handle<AllocationSite>::cast(object)->dependent_code();
11636 } 11700 }
11637 return Handle<Map>::cast(object)->dependent_code(); 11701 return Handle<Map>::cast(object)->dependent_code();
11638 } 11702 }
11639 11703
11640 11704
11641 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, 11705 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries,
11642 DependencyGroup group, 11706 DependencyGroup group,
11643 Handle<Object> object) { 11707 Handle<Object> object) {
11644 GroupStartIndexes starts(*entries); 11708 GroupStartIndexes starts(*entries);
11645 int start = starts.at(group); 11709 int start = starts.at(group);
11646 int end = starts.at(group + 1); 11710 int end = starts.at(group + 1);
11647 int number_of_entries = starts.number_of_entries(); 11711 int number_of_entries = starts.number_of_entries();
11648 if (start < end && entries->object_at(end - 1) == *object) { 11712 // Check for existing entry to avoid duplicates.
11649 // Do not append the compilation info if it is already in the array. 11713 for (int i = start; i < end; i++) {
11650 // It is sufficient to just check only the last element because 11714 if (entries->object_at(i) == *object) return entries;
11651 // we process embedded maps of an optimized code in one batch.
11652 return entries;
11653 } 11715 }
11654 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { 11716 if (entries->length() < kCodesStartIndex + number_of_entries + 1) {
11655 Factory* factory = entries->GetIsolate()->factory(); 11717 Factory* factory = entries->GetIsolate()->factory();
11656 int capacity = kCodesStartIndex + number_of_entries + 1; 11718 int capacity = kCodesStartIndex + number_of_entries + 1;
11657 if (capacity > 5) capacity = capacity * 5 / 4; 11719 if (capacity > 5) capacity = capacity * 5 / 4;
11658 Handle<DependentCode> new_entries = Handle<DependentCode>::cast( 11720 Handle<DependentCode> new_entries = Handle<DependentCode>::cast(
11659 factory->CopySizeFixedArray(entries, capacity, TENURED)); 11721 factory->CopySizeFixedArray(entries, capacity, TENURED));
11660 // The number of codes can change after GC. 11722 // The number of codes can change after GC.
11661 starts.Recompute(*entries); 11723 starts.Recompute(*entries);
11662 start = starts.at(group); 11724 start = starts.at(group);
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
11925 return JSObject::cast(proto)->GetLocalElementAccessorPair(index); 11987 return JSObject::cast(proto)->GetLocalElementAccessorPair(index);
11926 } 11988 }
11927 11989
11928 // Check for lookup interceptor. 11990 // Check for lookup interceptor.
11929 if (HasIndexedInterceptor()) return NULL; 11991 if (HasIndexedInterceptor()) return NULL;
11930 11992
11931 return GetElementsAccessor()->GetAccessorPair(this, this, index); 11993 return GetElementsAccessor()->GetAccessorPair(this, this, index);
11932 } 11994 }
11933 11995
11934 11996
11935 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, 11997 Handle<Object> JSObject::SetElementWithInterceptor(
11936 Object* value, 11998 Handle<JSObject> object,
11937 PropertyAttributes attributes, 11999 uint32_t index,
11938 StrictModeFlag strict_mode, 12000 Handle<Object> value,
11939 bool check_prototype, 12001 PropertyAttributes attributes,
11940 SetPropertyMode set_mode) { 12002 StrictModeFlag strict_mode,
11941 Isolate* isolate = GetIsolate(); 12003 bool check_prototype,
11942 HandleScope scope(isolate); 12004 SetPropertyMode set_mode) {
12005 Isolate* isolate = object->GetIsolate();
11943 12006
11944 // Make sure that the top context does not change when doing 12007 // Make sure that the top context does not change when doing
11945 // callbacks or interceptor calls. 12008 // callbacks or interceptor calls.
11946 AssertNoContextChange ncc(isolate); 12009 AssertNoContextChange ncc(isolate);
11947 12010
11948 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); 12011 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
11949 Handle<JSObject> this_handle(this);
11950 Handle<Object> value_handle(value, isolate);
11951 if (!interceptor->setter()->IsUndefined()) { 12012 if (!interceptor->setter()->IsUndefined()) {
11952 v8::IndexedPropertySetterCallback setter = 12013 v8::IndexedPropertySetterCallback setter =
11953 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); 12014 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
11954 LOG(isolate, 12015 LOG(isolate,
11955 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); 12016 ApiIndexedPropertyAccess("interceptor-indexed-set", *object, index));
11956 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); 12017 PropertyCallbackArguments args(isolate, interceptor->data(), *object,
12018 *object);
11957 v8::Handle<v8::Value> result = 12019 v8::Handle<v8::Value> result =
11958 args.Call(setter, index, v8::Utils::ToLocal(value_handle)); 12020 args.Call(setter, index, v8::Utils::ToLocal(value));
11959 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 12021 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
11960 if (!result.IsEmpty()) return *value_handle; 12022 if (!result.IsEmpty()) return value;
11961 } 12023 }
11962 MaybeObject* raw_result = 12024
11963 this_handle->SetElementWithoutInterceptor(index, 12025 return SetElementWithoutInterceptor(object, index, value, attributes,
11964 *value_handle, 12026 strict_mode,
11965 attributes, 12027 check_prototype,
11966 strict_mode, 12028 set_mode);
11967 check_prototype,
11968 set_mode);
11969 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
11970 return raw_result;
11971 } 12029 }
11972 12030
11973 12031
11974 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, 12032 MaybeObject* JSObject::GetElementWithCallback(Object* receiver,
11975 Object* structure, 12033 Object* structure,
11976 uint32_t index, 12034 uint32_t index,
11977 Object* holder) { 12035 Object* holder) {
11978 Isolate* isolate = GetIsolate(); 12036 Isolate* isolate = GetIsolate();
11979 ASSERT(!structure->IsForeign()); 12037 ASSERT(!structure->IsForeign());
11980 12038
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
12108 return false; 12166 return false;
12109 } 12167 }
12110 FixedArray* arguments = FixedArray::cast(elements->get(1)); 12168 FixedArray* arguments = FixedArray::cast(elements->get(1));
12111 return arguments->IsDictionary(); 12169 return arguments->IsDictionary();
12112 } 12170 }
12113 12171
12114 12172
12115 // Adding n elements in fast case is O(n*n). 12173 // Adding n elements in fast case is O(n*n).
12116 // Note: revisit design to have dual undefined values to capture absent 12174 // Note: revisit design to have dual undefined values to capture absent
12117 // elements. 12175 // elements.
12118 MaybeObject* JSObject::SetFastElement(uint32_t index, 12176 Handle<Object> JSObject::SetFastElement(Handle<JSObject> object,
12119 Object* value, 12177 uint32_t index,
12120 StrictModeFlag strict_mode, 12178 Handle<Object> value,
12121 bool check_prototype) { 12179 StrictModeFlag strict_mode,
12122 ASSERT(HasFastSmiOrObjectElements() || 12180 bool check_prototype) {
12123 HasFastArgumentsElements()); 12181 ASSERT(object->HasFastSmiOrObjectElements() ||
12182 object->HasFastArgumentsElements());
12183
12184 Isolate* isolate = object->GetIsolate();
12124 12185
12125 // Array optimizations rely on the prototype lookups of Array objects always 12186 // Array optimizations rely on the prototype lookups of Array objects always
12126 // returning undefined. If there is a store to the initial prototype object, 12187 // returning undefined. If there is a store to the initial prototype object,
12127 // make sure all of these optimizations are invalidated. 12188 // make sure all of these optimizations are invalidated.
12128 Isolate* isolate(GetIsolate()); 12189 if (isolate->is_initial_object_prototype(*object) ||
12129 if (isolate->is_initial_object_prototype(this) || 12190 isolate->is_initial_array_prototype(*object)) {
12130 isolate->is_initial_array_prototype(this)) { 12191 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate,
12131 HandleScope scope(GetIsolate());
12132 map()->dependent_code()->DeoptimizeDependentCodeGroup(
12133 GetIsolate(),
12134 DependentCode::kElementsCantBeAddedGroup); 12192 DependentCode::kElementsCantBeAddedGroup);
12135 } 12193 }
12136 12194
12137 FixedArray* backing_store = FixedArray::cast(elements()); 12195 Handle<FixedArray> backing_store(FixedArray::cast(object->elements()));
12138 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { 12196 if (backing_store->map() ==
12139 backing_store = FixedArray::cast(backing_store->get(1)); 12197 isolate->heap()->non_strict_arguments_elements_map()) {
12198 backing_store = handle(FixedArray::cast(backing_store->get(1)));
12140 } else { 12199 } else {
12141 MaybeObject* maybe = EnsureWritableFastElements(); 12200 backing_store = EnsureWritableFastElements(object);
12142 if (!maybe->To(&backing_store)) return maybe;
12143 } 12201 }
12144 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); 12202 uint32_t capacity = static_cast<uint32_t>(backing_store->length());
12145 12203
12146 if (check_prototype && 12204 if (check_prototype &&
12147 (index >= capacity || backing_store->get(index)->IsTheHole())) { 12205 (index >= capacity || backing_store->get(index)->IsTheHole())) {
12148 bool found; 12206 bool found;
12149 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, 12207 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(
12150 value, 12208 object, index, value, &found, strict_mode);
12151 &found,
12152 strict_mode);
12153 if (found) return result; 12209 if (found) return result;
12154 } 12210 }
12155 12211
12156 uint32_t new_capacity = capacity; 12212 uint32_t new_capacity = capacity;
12157 // Check if the length property of this object needs to be updated. 12213 // Check if the length property of this object needs to be updated.
12158 uint32_t array_length = 0; 12214 uint32_t array_length = 0;
12159 bool must_update_array_length = false; 12215 bool must_update_array_length = false;
12160 bool introduces_holes = true; 12216 bool introduces_holes = true;
12161 if (IsJSArray()) { 12217 if (object->IsJSArray()) {
12162 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); 12218 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length));
12163 introduces_holes = index > array_length; 12219 introduces_holes = index > array_length;
12164 if (index >= array_length) { 12220 if (index >= array_length) {
12165 must_update_array_length = true; 12221 must_update_array_length = true;
12166 array_length = index + 1; 12222 array_length = index + 1;
12167 } 12223 }
12168 } else { 12224 } else {
12169 introduces_holes = index >= capacity; 12225 introduces_holes = index >= capacity;
12170 } 12226 }
12171 12227
12172 // If the array is growing, and it's not growth by a single element at the 12228 // If the array is growing, and it's not growth by a single element at the
12173 // end, make sure that the ElementsKind is HOLEY. 12229 // end, make sure that the ElementsKind is HOLEY.
12174 ElementsKind elements_kind = GetElementsKind(); 12230 ElementsKind elements_kind = object->GetElementsKind();
12175 if (introduces_holes && 12231 if (introduces_holes &&
12176 IsFastElementsKind(elements_kind) && 12232 IsFastElementsKind(elements_kind) &&
12177 !IsFastHoleyElementsKind(elements_kind)) { 12233 !IsFastHoleyElementsKind(elements_kind)) {
12178 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); 12234 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind);
12179 MaybeObject* maybe = TransitionElementsKind(transitioned_kind); 12235 TransitionElementsKind(object, transitioned_kind);
12180 if (maybe->IsFailure()) return maybe;
12181 } 12236 }
12182 12237
12183 // Check if the capacity of the backing store needs to be increased, or if 12238 // Check if the capacity of the backing store needs to be increased, or if
12184 // a transition to slow elements is necessary. 12239 // a transition to slow elements is necessary.
12185 if (index >= capacity) { 12240 if (index >= capacity) {
12186 bool convert_to_slow = true; 12241 bool convert_to_slow = true;
12187 if ((index - capacity) < kMaxGap) { 12242 if ((index - capacity) < kMaxGap) {
12188 new_capacity = NewElementsCapacity(index + 1); 12243 new_capacity = NewElementsCapacity(index + 1);
12189 ASSERT(new_capacity > index); 12244 ASSERT(new_capacity > index);
12190 if (!ShouldConvertToSlowElements(new_capacity)) { 12245 if (!object->ShouldConvertToSlowElements(new_capacity)) {
12191 convert_to_slow = false; 12246 convert_to_slow = false;
12192 } 12247 }
12193 } 12248 }
12194 if (convert_to_slow) { 12249 if (convert_to_slow) {
12195 MaybeObject* result = NormalizeElements(); 12250 NormalizeElements(object);
12196 if (result->IsFailure()) return result; 12251 return SetDictionaryElement(object, index, value, NONE, strict_mode,
12197 return SetDictionaryElement(index, value, NONE, strict_mode,
12198 check_prototype); 12252 check_prototype);
12199 } 12253 }
12200 } 12254 }
12201 // Convert to fast double elements if appropriate. 12255 // Convert to fast double elements if appropriate.
12202 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { 12256 if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) {
12203 // Consider fixing the boilerplate as well if we have one. 12257 // Consider fixing the boilerplate as well if we have one.
12204 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) 12258 ElementsKind to_kind = IsHoleyElementsKind(elements_kind)
12205 ? FAST_HOLEY_DOUBLE_ELEMENTS 12259 ? FAST_HOLEY_DOUBLE_ELEMENTS
12206 : FAST_DOUBLE_ELEMENTS; 12260 : FAST_DOUBLE_ELEMENTS;
12207 12261
12208 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); 12262 UpdateAllocationSite(object, to_kind);
12209 if (maybe_failure->IsFailure()) return maybe_failure;
12210 12263
12211 MaybeObject* maybe = 12264 SetFastDoubleElementsCapacityAndLength(object, new_capacity, array_length);
12212 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); 12265 FixedDoubleArray::cast(object->elements())->set(index, value->Number());
12213 if (maybe->IsFailure()) return maybe; 12266 object->ValidateElements();
12214 FixedDoubleArray::cast(elements())->set(index, value->Number());
12215 ValidateElements();
12216 return value; 12267 return value;
12217 } 12268 }
12218 // Change elements kind from Smi-only to generic FAST if necessary. 12269 // Change elements kind from Smi-only to generic FAST if necessary.
12219 if (HasFastSmiElements() && !value->IsSmi()) { 12270 if (object->HasFastSmiElements() && !value->IsSmi()) {
12220 Map* new_map; 12271 ElementsKind kind = object->HasFastHoleyElements()
12221 ElementsKind kind = HasFastHoleyElements()
12222 ? FAST_HOLEY_ELEMENTS 12272 ? FAST_HOLEY_ELEMENTS
12223 : FAST_ELEMENTS; 12273 : FAST_ELEMENTS;
12224 12274
12225 MaybeObject* maybe_failure = UpdateAllocationSite(kind); 12275 UpdateAllocationSite(object, kind);
12226 if (maybe_failure->IsFailure()) return maybe_failure; 12276 Handle<Map> new_map = GetElementsTransitionMap(object, kind);
12227 12277 object->set_map(*new_map);
12228 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), 12278 ASSERT(IsFastObjectElementsKind(object->GetElementsKind()));
12229 kind);
12230 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
12231
12232 set_map(new_map);
12233 } 12279 }
12234 // Increase backing store capacity if that's been decided previously. 12280 // Increase backing store capacity if that's been decided previously.
12235 if (new_capacity != capacity) { 12281 if (new_capacity != capacity) {
12236 FixedArray* new_elements;
12237 SetFastElementsCapacitySmiMode smi_mode = 12282 SetFastElementsCapacitySmiMode smi_mode =
12238 value->IsSmi() && HasFastSmiElements() 12283 value->IsSmi() && object->HasFastSmiElements()
12239 ? kAllowSmiElements 12284 ? kAllowSmiElements
12240 : kDontAllowSmiElements; 12285 : kDontAllowSmiElements;
12241 { MaybeObject* maybe = 12286 Handle<FixedArray> new_elements =
12242 SetFastElementsCapacityAndLength(new_capacity, 12287 SetFastElementsCapacityAndLength(object, new_capacity, array_length,
12243 array_length, 12288 smi_mode);
12244 smi_mode); 12289 new_elements->set(index, *value);
12245 if (!maybe->To(&new_elements)) return maybe; 12290 object->ValidateElements();
12246 }
12247 new_elements->set(index, value);
12248 ValidateElements();
12249 return value; 12291 return value;
12250 } 12292 }
12251 12293
12252 // Finally, set the new element and length. 12294 // Finally, set the new element and length.
12253 ASSERT(elements()->IsFixedArray()); 12295 ASSERT(object->elements()->IsFixedArray());
12254 backing_store->set(index, value); 12296 backing_store->set(index, *value);
12255 if (must_update_array_length) { 12297 if (must_update_array_length) {
12256 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); 12298 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length));
12257 } 12299 }
12258 return value; 12300 return value;
12259 } 12301 }
12260 12302
12261 12303
12262 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, 12304 Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object,
12263 Object* value_raw, 12305 uint32_t index,
12264 PropertyAttributes attributes, 12306 Handle<Object> value,
12265 StrictModeFlag strict_mode, 12307 PropertyAttributes attributes,
12266 bool check_prototype, 12308 StrictModeFlag strict_mode,
12267 SetPropertyMode set_mode) { 12309 bool check_prototype,
12268 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 12310 SetPropertyMode set_mode) {
12269 Isolate* isolate = GetIsolate(); 12311 ASSERT(object->HasDictionaryElements() ||
12270 Heap* heap = isolate->heap(); 12312 object->HasDictionaryArgumentsElements());
12271 Handle<JSObject> self(this); 12313 Isolate* isolate = object->GetIsolate();
12272 Handle<Object> value(value_raw, isolate);
12273 12314
12274 // Insert element in the dictionary. 12315 // Insert element in the dictionary.
12275 Handle<FixedArray> elements(FixedArray::cast(this->elements())); 12316 Handle<FixedArray> elements(FixedArray::cast(object->elements()));
12276 bool is_arguments = 12317 bool is_arguments =
12277 (elements->map() == heap->non_strict_arguments_elements_map()); 12318 (elements->map() == isolate->heap()->non_strict_arguments_elements_map());
12278 Handle<SeededNumberDictionary> dictionary(is_arguments 12319 Handle<SeededNumberDictionary> dictionary(is_arguments
12279 ? SeededNumberDictionary::cast(elements->get(1)) 12320 ? SeededNumberDictionary::cast(elements->get(1))
12280 : SeededNumberDictionary::cast(*elements)); 12321 : SeededNumberDictionary::cast(*elements));
12281 12322
12282 int entry = dictionary->FindEntry(index); 12323 int entry = dictionary->FindEntry(index);
12283 if (entry != SeededNumberDictionary::kNotFound) { 12324 if (entry != SeededNumberDictionary::kNotFound) {
12284 Handle<Object> element(dictionary->ValueAt(entry), isolate); 12325 Handle<Object> element(dictionary->ValueAt(entry), isolate);
12285 PropertyDetails details = dictionary->DetailsAt(entry); 12326 PropertyDetails details = dictionary->DetailsAt(entry);
12286 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { 12327 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) {
12287 Handle<Object> result = SetElementWithCallback(self, element, index, 12328 return SetElementWithCallback(object, element, index, value, object,
12288 value, self, strict_mode); 12329 strict_mode);
12289 RETURN_IF_EMPTY_HANDLE(isolate, result);
12290 return *result;
12291 } else { 12330 } else {
12292 dictionary->UpdateMaxNumberKey(index); 12331 dictionary->UpdateMaxNumberKey(index);
12293 // If a value has not been initialized we allow writing to it even if it 12332 // If a value has not been initialized we allow writing to it even if it
12294 // is read-only (a declared const that has not been initialized). If a 12333 // is read-only (a declared const that has not been initialized). If a
12295 // value is being defined we skip attribute checks completely. 12334 // value is being defined we skip attribute checks completely.
12296 if (set_mode == DEFINE_PROPERTY) { 12335 if (set_mode == DEFINE_PROPERTY) {
12297 details = PropertyDetails( 12336 details = PropertyDetails(
12298 attributes, NORMAL, details.dictionary_index()); 12337 attributes, NORMAL, details.dictionary_index());
12299 dictionary->DetailsAtPut(entry, details); 12338 dictionary->DetailsAtPut(entry, details);
12300 } else if (details.IsReadOnly() && !element->IsTheHole()) { 12339 } else if (details.IsReadOnly() && !element->IsTheHole()) {
12301 if (strict_mode == kNonStrictMode) { 12340 if (strict_mode == kNonStrictMode) {
12302 return isolate->heap()->undefined_value(); 12341 return isolate->factory()->undefined_value();
12303 } else { 12342 } else {
12304 Handle<Object> holder(this, isolate);
12305 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12343 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12306 Handle<Object> args[2] = { number, holder }; 12344 Handle<Object> args[2] = { number, object };
12307 Handle<Object> error = 12345 Handle<Object> error =
12308 isolate->factory()->NewTypeError("strict_read_only_property", 12346 isolate->factory()->NewTypeError("strict_read_only_property",
12309 HandleVector(args, 2)); 12347 HandleVector(args, 2));
12310 return isolate->Throw(*error); 12348 isolate->Throw(*error);
12349 return Handle<Object>();
12311 } 12350 }
12312 } 12351 }
12313 // Elements of the arguments object in slow mode might be slow aliases. 12352 // Elements of the arguments object in slow mode might be slow aliases.
12314 if (is_arguments && element->IsAliasedArgumentsEntry()) { 12353 if (is_arguments && element->IsAliasedArgumentsEntry()) {
12315 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*element); 12354 Handle<AliasedArgumentsEntry> entry =
12316 Context* context = Context::cast(elements->get(0)); 12355 Handle<AliasedArgumentsEntry>::cast(element);
12356 Handle<Context> context(Context::cast(elements->get(0)));
12317 int context_index = entry->aliased_context_slot(); 12357 int context_index = entry->aliased_context_slot();
12318 ASSERT(!context->get(context_index)->IsTheHole()); 12358 ASSERT(!context->get(context_index)->IsTheHole());
12319 context->set(context_index, *value); 12359 context->set(context_index, *value);
12320 // For elements that are still writable we keep slow aliasing. 12360 // For elements that are still writable we keep slow aliasing.
12321 if (!details.IsReadOnly()) value = element; 12361 if (!details.IsReadOnly()) value = element;
12322 } 12362 }
12323 dictionary->ValueAtPut(entry, *value); 12363 dictionary->ValueAtPut(entry, *value);
12324 } 12364 }
12325 } else { 12365 } else {
12326 // Index not already used. Look for an accessor in the prototype chain. 12366 // Index not already used. Look for an accessor in the prototype chain.
12327 // Can cause GC! 12367 // Can cause GC!
12328 if (check_prototype) { 12368 if (check_prototype) {
12329 bool found; 12369 bool found;
12330 MaybeObject* result = SetElementWithCallbackSetterInPrototypes( 12370 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object,
12331 index, *value, &found, strict_mode); 12371 index, value, &found, strict_mode);
12332 if (found) return result; 12372 if (found) return result;
12333 } 12373 }
12374
12334 // When we set the is_extensible flag to false we always force the 12375 // When we set the is_extensible flag to false we always force the
12335 // element into dictionary mode (and force them to stay there). 12376 // element into dictionary mode (and force them to stay there).
12336 if (!self->map()->is_extensible()) { 12377 if (!object->map()->is_extensible()) {
12337 if (strict_mode == kNonStrictMode) { 12378 if (strict_mode == kNonStrictMode) {
12338 return isolate->heap()->undefined_value(); 12379 return isolate->factory()->undefined_value();
12339 } else { 12380 } else {
12340 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12381 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12341 Handle<String> name = isolate->factory()->NumberToString(number); 12382 Handle<String> name = isolate->factory()->NumberToString(number);
12342 Handle<Object> args[1] = { name }; 12383 Handle<Object> args[1] = { name };
12343 Handle<Object> error = 12384 Handle<Object> error =
12344 isolate->factory()->NewTypeError("object_not_extensible", 12385 isolate->factory()->NewTypeError("object_not_extensible",
12345 HandleVector(args, 1)); 12386 HandleVector(args, 1));
12346 return isolate->Throw(*error); 12387 isolate->Throw(*error);
12388 return Handle<Object>();
12347 } 12389 }
12348 } 12390 }
12349 FixedArrayBase* new_dictionary; 12391
12350 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); 12392 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
12351 MaybeObject* maybe = dictionary->AddNumberEntry(index, *value, details); 12393 Handle<SeededNumberDictionary> new_dictionary =
12352 if (!maybe->To(&new_dictionary)) return maybe; 12394 SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
12353 if (*dictionary != SeededNumberDictionary::cast(new_dictionary)) { 12395 details);
12396 if (*dictionary != *new_dictionary) {
12354 if (is_arguments) { 12397 if (is_arguments) {
12355 elements->set(1, new_dictionary); 12398 elements->set(1, *new_dictionary);
12356 } else { 12399 } else {
12357 self->set_elements(new_dictionary); 12400 object->set_elements(*new_dictionary);
12358 } 12401 }
12359 dictionary = 12402 dictionary = new_dictionary;
12360 handle(SeededNumberDictionary::cast(new_dictionary), isolate);
12361 } 12403 }
12362 } 12404 }
12363 12405
12364 // Update the array length if this JSObject is an array. 12406 // Update the array length if this JSObject is an array.
12365 if (self->IsJSArray()) { 12407 if (object->IsJSArray()) {
12366 MaybeObject* result = 12408 JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index,
12367 JSArray::cast(*self)->JSArrayUpdateLengthFromIndex(index, *value); 12409 value);
12368 if (result->IsFailure()) return result;
12369 } 12410 }
12370 12411
12371 // Attempt to put this object back in fast case. 12412 // Attempt to put this object back in fast case.
12372 if (self->ShouldConvertToFastElements()) { 12413 if (object->ShouldConvertToFastElements()) {
12373 uint32_t new_length = 0; 12414 uint32_t new_length = 0;
12374 if (self->IsJSArray()) { 12415 if (object->IsJSArray()) {
12375 CHECK(JSArray::cast(*self)->length()->ToArrayIndex(&new_length)); 12416 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&new_length));
12376 } else { 12417 } else {
12377 new_length = dictionary->max_number_key() + 1; 12418 new_length = dictionary->max_number_key() + 1;
12378 } 12419 }
12379 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays 12420 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays
12380 ? kAllowSmiElements 12421 ? kAllowSmiElements
12381 : kDontAllowSmiElements; 12422 : kDontAllowSmiElements;
12382 bool has_smi_only_elements = false; 12423 bool has_smi_only_elements = false;
12383 bool should_convert_to_fast_double_elements = 12424 bool should_convert_to_fast_double_elements =
12384 self->ShouldConvertToFastDoubleElements(&has_smi_only_elements); 12425 object->ShouldConvertToFastDoubleElements(&has_smi_only_elements);
12385 if (has_smi_only_elements) { 12426 if (has_smi_only_elements) {
12386 smi_mode = kForceSmiElements; 12427 smi_mode = kForceSmiElements;
12387 } 12428 }
12388 MaybeObject* result = should_convert_to_fast_double_elements 12429
12389 ? self->SetFastDoubleElementsCapacityAndLength(new_length, new_length) 12430 if (should_convert_to_fast_double_elements) {
12390 : self->SetFastElementsCapacityAndLength( 12431 SetFastDoubleElementsCapacityAndLength(object, new_length, new_length);
12391 new_length, new_length, smi_mode); 12432 } else {
12392 self->ValidateElements(); 12433 SetFastElementsCapacityAndLength(object, new_length, new_length,
12393 if (result->IsFailure()) return result; 12434 smi_mode);
12435 }
12436 object->ValidateElements();
12394 #ifdef DEBUG 12437 #ifdef DEBUG
12395 if (FLAG_trace_normalization) { 12438 if (FLAG_trace_normalization) {
12396 PrintF("Object elements are fast case again:\n"); 12439 PrintF("Object elements are fast case again:\n");
12397 Print(); 12440 object->Print();
12398 } 12441 }
12399 #endif 12442 #endif
12400 } 12443 }
12401 return *value; 12444 return value;
12402 } 12445 }
12403 12446
12404 12447 Handle<Object> JSObject::SetFastDoubleElement(
12405 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( 12448 Handle<JSObject> object,
12406 uint32_t index, 12449 uint32_t index,
12407 Object* value, 12450 Handle<Object> value,
12408 StrictModeFlag strict_mode, 12451 StrictModeFlag strict_mode,
12409 bool check_prototype) { 12452 bool check_prototype) {
12410 ASSERT(HasFastDoubleElements()); 12453 ASSERT(object->HasFastDoubleElements());
12411 12454
12412 FixedArrayBase* base_elms = FixedArrayBase::cast(elements()); 12455 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements()));
12413 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); 12456 uint32_t elms_length = static_cast<uint32_t>(base_elms->length());
12414 12457
12415 // If storing to an element that isn't in the array, pass the store request 12458 // If storing to an element that isn't in the array, pass the store request
12416 // up the prototype chain before storing in the receiver's elements. 12459 // up the prototype chain before storing in the receiver's elements.
12417 if (check_prototype && 12460 if (check_prototype &&
12418 (index >= elms_length || 12461 (index >= elms_length ||
12419 FixedDoubleArray::cast(base_elms)->is_the_hole(index))) { 12462 Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) {
12420 bool found; 12463 bool found;
12421 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, 12464 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object,
12422 value, 12465 index, value, &found, strict_mode);
12423 &found,
12424 strict_mode);
12425 if (found) return result; 12466 if (found) return result;
12426 } 12467 }
12427 12468
12428 // If the value object is not a heap number, switch to fast elements and try 12469 // If the value object is not a heap number, switch to fast elements and try
12429 // again. 12470 // again.
12430 bool value_is_smi = value->IsSmi(); 12471 bool value_is_smi = value->IsSmi();
12431 bool introduces_holes = true; 12472 bool introduces_holes = true;
12432 uint32_t length = elms_length; 12473 uint32_t length = elms_length;
12433 if (IsJSArray()) { 12474 if (object->IsJSArray()) {
12434 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); 12475 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length));
12435 introduces_holes = index > length; 12476 introduces_holes = index > length;
12436 } else { 12477 } else {
12437 introduces_holes = index >= elms_length; 12478 introduces_holes = index >= elms_length;
12438 } 12479 }
12439 12480
12440 if (!value->IsNumber()) { 12481 if (!value->IsNumber()) {
12441 MaybeObject* maybe_obj = SetFastElementsCapacityAndLength( 12482 SetFastElementsCapacityAndLength(object, elms_length, length,
12442 elms_length, 12483 kDontAllowSmiElements);
12443 length, 12484 Handle<Object> result = SetFastElement(object, index, value, strict_mode,
12444 kDontAllowSmiElements); 12485 check_prototype);
12445 if (maybe_obj->IsFailure()) return maybe_obj; 12486 RETURN_IF_EMPTY_HANDLE_VALUE(object->GetIsolate(), result,
12446 maybe_obj = SetFastElement(index, value, strict_mode, check_prototype); 12487 Handle<Object>());
12447 if (maybe_obj->IsFailure()) return maybe_obj; 12488 object->ValidateElements();
12448 ValidateElements(); 12489 return result;
12449 return maybe_obj;
12450 } 12490 }
12451 12491
12452 double double_value = value_is_smi 12492 double double_value = value_is_smi
12453 ? static_cast<double>(Smi::cast(value)->value()) 12493 ? static_cast<double>(Handle<Smi>::cast(value)->value())
12454 : HeapNumber::cast(value)->value(); 12494 : Handle<HeapNumber>::cast(value)->value();
12455 12495
12456 // If the array is growing, and it's not growth by a single element at the 12496 // If the array is growing, and it's not growth by a single element at the
12457 // end, make sure that the ElementsKind is HOLEY. 12497 // end, make sure that the ElementsKind is HOLEY.
12458 ElementsKind elements_kind = GetElementsKind(); 12498 ElementsKind elements_kind = object->GetElementsKind();
12459 if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) { 12499 if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) {
12460 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); 12500 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind);
12461 MaybeObject* maybe = TransitionElementsKind(transitioned_kind); 12501 TransitionElementsKind(object, transitioned_kind);
12462 if (maybe->IsFailure()) return maybe;
12463 } 12502 }
12464 12503
12465 // Check whether there is extra space in the fixed array. 12504 // Check whether there is extra space in the fixed array.
12466 if (index < elms_length) { 12505 if (index < elms_length) {
12467 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); 12506 Handle<FixedDoubleArray> elms(FixedDoubleArray::cast(object->elements()));
12468 elms->set(index, double_value); 12507 elms->set(index, double_value);
12469 if (IsJSArray()) { 12508 if (object->IsJSArray()) {
12470 // Update the length of the array if needed. 12509 // Update the length of the array if needed.
12471 uint32_t array_length = 0; 12510 uint32_t array_length = 0;
12472 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); 12511 CHECK(
12512 Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length));
12473 if (index >= array_length) { 12513 if (index >= array_length) {
12474 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); 12514 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(index + 1));
12475 } 12515 }
12476 } 12516 }
12477 return value; 12517 return value;
12478 } 12518 }
12479 12519
12480 // Allow gap in fast case. 12520 // Allow gap in fast case.
12481 if ((index - elms_length) < kMaxGap) { 12521 if ((index - elms_length) < kMaxGap) {
12482 // Try allocating extra space. 12522 // Try allocating extra space.
12483 int new_capacity = NewElementsCapacity(index+1); 12523 int new_capacity = NewElementsCapacity(index+1);
12484 if (!ShouldConvertToSlowElements(new_capacity)) { 12524 if (!object->ShouldConvertToSlowElements(new_capacity)) {
12485 ASSERT(static_cast<uint32_t>(new_capacity) > index); 12525 ASSERT(static_cast<uint32_t>(new_capacity) > index);
12486 MaybeObject* maybe_obj = 12526 SetFastDoubleElementsCapacityAndLength(object, new_capacity, index + 1);
12487 SetFastDoubleElementsCapacityAndLength(new_capacity, index + 1); 12527 FixedDoubleArray::cast(object->elements())->set(index, double_value);
12488 if (maybe_obj->IsFailure()) return maybe_obj; 12528 object->ValidateElements();
12489 FixedDoubleArray::cast(elements())->set(index, double_value);
12490 ValidateElements();
12491 return value; 12529 return value;
12492 } 12530 }
12493 } 12531 }
12494 12532
12495 // Otherwise default to slow case. 12533 // Otherwise default to slow case.
12496 ASSERT(HasFastDoubleElements()); 12534 ASSERT(object->HasFastDoubleElements());
12497 ASSERT(map()->has_fast_double_elements()); 12535 ASSERT(object->map()->has_fast_double_elements());
12498 ASSERT(elements()->IsFixedDoubleArray()); 12536 ASSERT(object->elements()->IsFixedDoubleArray());
12499 Object* obj; 12537
12500 { MaybeObject* maybe_obj = NormalizeElements(); 12538 NormalizeElements(object);
12501 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 12539 ASSERT(object->HasDictionaryElements());
12502 } 12540 return SetElement(object, index, value, NONE, strict_mode, check_prototype);
12503 ASSERT(HasDictionaryElements());
12504 return SetElement(index, value, NONE, strict_mode, check_prototype);
12505 } 12541 }
12506 12542
12507 12543
12508 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, 12544 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
12509 uint32_t index, 12545 uint32_t index,
12510 Handle<Object> value, 12546 Handle<Object> value,
12511 PropertyAttributes attributes, 12547 PropertyAttributes attributes,
12512 StrictModeFlag strict_mode) { 12548 StrictModeFlag strict_mode) {
12513 if (object->IsJSProxy()) { 12549 if (object->IsJSProxy()) {
12514 return JSProxy::SetElementWithHandler( 12550 return JSProxy::SetElementWithHandler(
12515 Handle<JSProxy>::cast(object), object, index, value, strict_mode); 12551 Handle<JSProxy>::cast(object), object, index, value, strict_mode);
12516 } 12552 }
12517 return JSObject::SetElement( 12553 return JSObject::SetElement(
12518 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); 12554 Handle<JSObject>::cast(object), index, value, attributes, strict_mode);
12519 } 12555 }
12520 12556
12521 12557
12522 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, 12558 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object,
12523 uint32_t index, 12559 uint32_t index,
12524 Handle<Object> value, 12560 Handle<Object> value,
12525 StrictModeFlag strict_mode) { 12561 StrictModeFlag strict_mode) {
12526 ASSERT(!object->HasExternalArrayElements()); 12562 ASSERT(!object->HasExternalArrayElements());
12527 CALL_HEAP_FUNCTION( 12563 return JSObject::SetElement(object, index, value, NONE, strict_mode, false);
12528 object->GetIsolate(),
12529 object->SetElement(index, *value, NONE, strict_mode, false),
12530 Object);
12531 } 12564 }
12532 12565
12533 12566
12534 Handle<Object> JSObject::SetElement(Handle<JSObject> object, 12567 Handle<Object> JSObject::SetElement(Handle<JSObject> object,
12535 uint32_t index, 12568 uint32_t index,
12536 Handle<Object> value, 12569 Handle<Object> value,
12537 PropertyAttributes attr, 12570 PropertyAttributes attributes,
12538 StrictModeFlag strict_mode, 12571 StrictModeFlag strict_mode,
12539 bool check_prototype, 12572 bool check_prototype,
12540 SetPropertyMode set_mode) { 12573 SetPropertyMode set_mode) {
12574 Isolate* isolate = object->GetIsolate();
12575
12541 if (object->HasExternalArrayElements()) { 12576 if (object->HasExternalArrayElements()) {
12542 if (!value->IsNumber() && !value->IsUndefined()) { 12577 if (!value->IsNumber() && !value->IsUndefined()) {
12543 bool has_exception; 12578 bool has_exception;
12544 Handle<Object> number = 12579 Handle<Object> number =
12545 Execution::ToNumber(object->GetIsolate(), value, &has_exception); 12580 Execution::ToNumber(isolate, value, &has_exception);
12546 if (has_exception) return Handle<Object>(); 12581 if (has_exception) return Handle<Object>();
12547 value = number; 12582 value = number;
12548 } 12583 }
12549 } 12584 }
12550 CALL_HEAP_FUNCTION(
12551 object->GetIsolate(),
12552 object->SetElement(index, *value, attr, strict_mode, check_prototype,
12553 set_mode),
12554 Object);
12555 }
12556
12557
12558 MaybeObject* JSObject::SetElement(uint32_t index,
12559 Object* value_raw,
12560 PropertyAttributes attributes,
12561 StrictModeFlag strict_mode,
12562 bool check_prototype,
12563 SetPropertyMode set_mode) {
12564 Isolate* isolate = GetIsolate();
12565 12585
12566 // Check access rights if needed. 12586 // Check access rights if needed.
12567 if (IsAccessCheckNeeded()) { 12587 if (object->IsAccessCheckNeeded()) {
12568 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_SET)) { 12588 if (!isolate->MayIndexedAccess(*object, index, v8::ACCESS_SET)) {
12569 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 12589 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
12570 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 12590 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
12571 return value_raw; 12591 return value;
12572 } 12592 }
12573 } 12593 }
12574 12594
12575 if (IsJSGlobalProxy()) { 12595 if (object->IsJSGlobalProxy()) {
12576 Object* proto = GetPrototype(); 12596 Handle<Object> proto(object->GetPrototype(), isolate);
12577 if (proto->IsNull()) return value_raw; 12597 if (proto->IsNull()) return value;
12578 ASSERT(proto->IsJSGlobalObject()); 12598 ASSERT(proto->IsJSGlobalObject());
12579 return JSObject::cast(proto)->SetElement(index, 12599 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes,
12580 value_raw, 12600 strict_mode,
12581 attributes, 12601 check_prototype,
12582 strict_mode, 12602 set_mode);
12583 check_prototype,
12584 set_mode);
12585 } 12603 }
12586 12604
12587 // Don't allow element properties to be redefined for external arrays. 12605 // Don't allow element properties to be redefined for external arrays.
12588 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { 12606 if (object->HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) {
12589 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 12607 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
12590 Handle<Object> args[] = { handle(this, isolate), number }; 12608 Handle<Object> args[] = { object, number };
12591 Handle<Object> error = isolate->factory()->NewTypeError( 12609 Handle<Object> error = isolate->factory()->NewTypeError(
12592 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); 12610 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args)));
12593 return isolate->Throw(*error); 12611 isolate->Throw(*error);
12612 return Handle<Object>();
12594 } 12613 }
12595 12614
12596 // Normalize the elements to enable attributes on the property. 12615 // Normalize the elements to enable attributes on the property.
12597 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { 12616 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) {
12598 SeededNumberDictionary* dictionary; 12617 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
12599 MaybeObject* maybe_object = NormalizeElements();
12600 if (!maybe_object->To(&dictionary)) return maybe_object;
12601 // Make sure that we never go back to fast case. 12618 // Make sure that we never go back to fast case.
12602 dictionary->set_requires_slow_elements(); 12619 dictionary->set_requires_slow_elements();
12603 } 12620 }
12604 12621
12605 if (!(FLAG_harmony_observation && map()->is_observed())) { 12622 if (!(FLAG_harmony_observation && object->map()->is_observed())) {
12606 return HasIndexedInterceptor() 12623 return object->HasIndexedInterceptor()
12607 ? SetElementWithInterceptor( 12624 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode,
12608 index, value_raw, attributes, strict_mode, check_prototype, set_mode) 12625 check_prototype,
12609 : SetElementWithoutInterceptor( 12626 set_mode)
12610 index, value_raw, attributes, strict_mode, check_prototype, set_mode); 12627 : SetElementWithoutInterceptor(object, index, value, attributes,
12611 } 12628 strict_mode,
12612 12629 check_prototype,
12613 // From here on, everything has to be handlified. 12630 set_mode);
12614 Handle<JSObject> self(this); 12631 }
12615 Handle<Object> value(value_raw, isolate); 12632
12616 PropertyAttributes old_attributes = self->GetLocalElementAttribute(index); 12633 PropertyAttributes old_attributes = object->GetLocalElementAttribute(index);
12617 Handle<Object> old_value = isolate->factory()->the_hole_value(); 12634 Handle<Object> old_value = isolate->factory()->the_hole_value();
12618 Handle<Object> old_length_handle; 12635 Handle<Object> old_length_handle;
12619 Handle<Object> new_length_handle; 12636 Handle<Object> new_length_handle;
12620 12637
12621 if (old_attributes != ABSENT) { 12638 if (old_attributes != ABSENT) {
12622 if (self->GetLocalElementAccessorPair(index) == NULL) 12639 if (object->GetLocalElementAccessorPair(index) == NULL)
12623 old_value = Object::GetElement(isolate, self, index); 12640 old_value = Object::GetElement(isolate, object, index);
12624 } else if (self->IsJSArray()) { 12641 } else if (object->IsJSArray()) {
12625 // Store old array length in case adding an element grows the array. 12642 // Store old array length in case adding an element grows the array.
12626 old_length_handle = handle(Handle<JSArray>::cast(self)->length(), isolate); 12643 old_length_handle = handle(Handle<JSArray>::cast(object)->length(),
12644 isolate);
12627 } 12645 }
12628 12646
12629 // Check for lookup interceptor 12647 // Check for lookup interceptor
12630 MaybeObject* result = self->HasIndexedInterceptor() 12648 Handle<Object> result = object->HasIndexedInterceptor()
12631 ? self->SetElementWithInterceptor( 12649 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode,
12632 index, *value, attributes, strict_mode, check_prototype, set_mode) 12650 check_prototype,
12633 : self->SetElementWithoutInterceptor( 12651 set_mode)
12634 index, *value, attributes, strict_mode, check_prototype, set_mode); 12652 : SetElementWithoutInterceptor(object, index, value, attributes,
12635 12653 strict_mode,
12636 Handle<Object> hresult; 12654 check_prototype,
12637 if (!result->ToHandle(&hresult, isolate)) return result; 12655 set_mode);
12656 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>());
12638 12657
12639 Handle<String> name = isolate->factory()->Uint32ToString(index); 12658 Handle<String> name = isolate->factory()->Uint32ToString(index);
12640 PropertyAttributes new_attributes = self->GetLocalElementAttribute(index); 12659 PropertyAttributes new_attributes = object->GetLocalElementAttribute(index);
12641 if (old_attributes == ABSENT) { 12660 if (old_attributes == ABSENT) {
12642 if (self->IsJSArray() && 12661 if (object->IsJSArray() &&
12643 !old_length_handle->SameValue(Handle<JSArray>::cast(self)->length())) { 12662 !old_length_handle->SameValue(
12644 new_length_handle = handle(Handle<JSArray>::cast(self)->length(), 12663 Handle<JSArray>::cast(object)->length())) {
12664 new_length_handle = handle(Handle<JSArray>::cast(object)->length(),
12645 isolate); 12665 isolate);
12646 uint32_t old_length = 0; 12666 uint32_t old_length = 0;
12647 uint32_t new_length = 0; 12667 uint32_t new_length = 0;
12648 CHECK(old_length_handle->ToArrayIndex(&old_length)); 12668 CHECK(old_length_handle->ToArrayIndex(&old_length));
12649 CHECK(new_length_handle->ToArrayIndex(&new_length)); 12669 CHECK(new_length_handle->ToArrayIndex(&new_length));
12650 12670
12651 BeginPerformSplice(Handle<JSArray>::cast(self)); 12671 BeginPerformSplice(Handle<JSArray>::cast(object));
12652 EnqueueChangeRecord(self, "add", name, old_value); 12672 EnqueueChangeRecord(object, "add", name, old_value);
12653 EnqueueChangeRecord(self, "update", isolate->factory()->length_string(), 12673 EnqueueChangeRecord(object, "update", isolate->factory()->length_string(),
12654 old_length_handle); 12674 old_length_handle);
12655 EndPerformSplice(Handle<JSArray>::cast(self)); 12675 EndPerformSplice(Handle<JSArray>::cast(object));
12656 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); 12676 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
12657 EnqueueSpliceRecord(Handle<JSArray>::cast(self), old_length, deleted, 12677 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted,
12658 new_length - old_length); 12678 new_length - old_length);
12659 } else { 12679 } else {
12660 EnqueueChangeRecord(self, "add", name, old_value); 12680 EnqueueChangeRecord(object, "add", name, old_value);
12661 } 12681 }
12662 } else if (old_value->IsTheHole()) { 12682 } else if (old_value->IsTheHole()) {
12663 EnqueueChangeRecord(self, "reconfigure", name, old_value); 12683 EnqueueChangeRecord(object, "reconfigure", name, old_value);
12664 } else { 12684 } else {
12665 Handle<Object> new_value = Object::GetElement(isolate, self, index); 12685 Handle<Object> new_value = Object::GetElement(isolate, object, index);
12666 bool value_changed = !old_value->SameValue(*new_value); 12686 bool value_changed = !old_value->SameValue(*new_value);
12667 if (old_attributes != new_attributes) { 12687 if (old_attributes != new_attributes) {
12668 if (!value_changed) old_value = isolate->factory()->the_hole_value(); 12688 if (!value_changed) old_value = isolate->factory()->the_hole_value();
12669 EnqueueChangeRecord(self, "reconfigure", name, old_value); 12689 EnqueueChangeRecord(object, "reconfigure", name, old_value);
12670 } else if (value_changed) { 12690 } else if (value_changed) {
12671 EnqueueChangeRecord(self, "update", name, old_value); 12691 EnqueueChangeRecord(object, "update", name, old_value);
12672 } 12692 }
12673 } 12693 }
12674 12694
12675 return *hresult; 12695 return result;
12676 } 12696 }
12677 12697
12678 12698
12679 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, 12699 Handle<Object> JSObject::SetElementWithoutInterceptor(
12680 Object* value, 12700 Handle<JSObject> object,
12681 PropertyAttributes attr, 12701 uint32_t index,
12682 StrictModeFlag strict_mode, 12702 Handle<Object> value,
12683 bool check_prototype, 12703 PropertyAttributes attributes,
12684 SetPropertyMode set_mode) { 12704 StrictModeFlag strict_mode,
12685 ASSERT(HasDictionaryElements() || 12705 bool check_prototype,
12686 HasDictionaryArgumentsElements() || 12706 SetPropertyMode set_mode) {
12687 (attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); 12707 ASSERT(object->HasDictionaryElements() ||
12688 Isolate* isolate = GetIsolate(); 12708 object->HasDictionaryArgumentsElements() ||
12709 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0);
12710 Isolate* isolate = object->GetIsolate();
12689 if (FLAG_trace_external_array_abuse && 12711 if (FLAG_trace_external_array_abuse &&
12690 IsExternalArrayElementsKind(GetElementsKind())) { 12712 IsExternalArrayElementsKind(object->GetElementsKind())) {
12691 CheckArrayAbuse(this, "external elements write", index); 12713 CheckArrayAbuse(*object, "external elements write", index);
12692 } 12714 }
12693 if (FLAG_trace_js_array_abuse && 12715 if (FLAG_trace_js_array_abuse &&
12694 !IsExternalArrayElementsKind(GetElementsKind())) { 12716 !IsExternalArrayElementsKind(object->GetElementsKind())) {
12695 if (IsJSArray()) { 12717 if (object->IsJSArray()) {
12696 CheckArrayAbuse(this, "elements write", index, true); 12718 CheckArrayAbuse(*object, "elements write", index, true);
12697 } 12719 }
12698 } 12720 }
12699 switch (GetElementsKind()) { 12721 switch (object->GetElementsKind()) {
12700 case FAST_SMI_ELEMENTS: 12722 case FAST_SMI_ELEMENTS:
12701 case FAST_ELEMENTS: 12723 case FAST_ELEMENTS:
12702 case FAST_HOLEY_SMI_ELEMENTS: 12724 case FAST_HOLEY_SMI_ELEMENTS:
12703 case FAST_HOLEY_ELEMENTS: 12725 case FAST_HOLEY_ELEMENTS:
12704 return SetFastElement(index, value, strict_mode, check_prototype); 12726 return SetFastElement(object, index, value, strict_mode, check_prototype);
12705 case FAST_DOUBLE_ELEMENTS: 12727 case FAST_DOUBLE_ELEMENTS:
12706 case FAST_HOLEY_DOUBLE_ELEMENTS: 12728 case FAST_HOLEY_DOUBLE_ELEMENTS:
12707 return SetFastDoubleElement(index, value, strict_mode, check_prototype); 12729 return SetFastDoubleElement(object, index, value, strict_mode,
12730 check_prototype);
12708 case EXTERNAL_PIXEL_ELEMENTS: { 12731 case EXTERNAL_PIXEL_ELEMENTS: {
12709 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 12732 ExternalPixelArray* pixels = ExternalPixelArray::cast(object->elements());
12710 return pixels->SetValue(index, value); 12733 return handle(pixels->SetValue(index, *value), isolate);
12711 } 12734 }
12712 case EXTERNAL_BYTE_ELEMENTS: { 12735 case EXTERNAL_BYTE_ELEMENTS: {
12713 ExternalByteArray* array = ExternalByteArray::cast(elements()); 12736 Handle<ExternalByteArray> array(
12714 return array->SetValue(index, value); 12737 ExternalByteArray::cast(object->elements()));
12738 return ExternalByteArray::SetValue(array, index, value);
12715 } 12739 }
12716 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { 12740 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
12717 ExternalUnsignedByteArray* array = 12741 Handle<ExternalUnsignedByteArray> array(
12718 ExternalUnsignedByteArray::cast(elements()); 12742 ExternalUnsignedByteArray::cast(object->elements()));
12719 return array->SetValue(index, value); 12743 return ExternalUnsignedByteArray::SetValue(array, index, value);
12720 } 12744 }
12721 case EXTERNAL_SHORT_ELEMENTS: { 12745 case EXTERNAL_SHORT_ELEMENTS: {
12722 ExternalShortArray* array = ExternalShortArray::cast(elements()); 12746 Handle<ExternalShortArray> array(ExternalShortArray::cast(
12723 return array->SetValue(index, value); 12747 object->elements()));
12748 return ExternalShortArray::SetValue(array, index, value);
12724 } 12749 }
12725 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { 12750 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
12726 ExternalUnsignedShortArray* array = 12751 Handle<ExternalUnsignedShortArray> array(
12727 ExternalUnsignedShortArray::cast(elements()); 12752 ExternalUnsignedShortArray::cast(object->elements()));
12728 return array->SetValue(index, value); 12753 return ExternalUnsignedShortArray::SetValue(array, index, value);
12729 } 12754 }
12730 case EXTERNAL_INT_ELEMENTS: { 12755 case EXTERNAL_INT_ELEMENTS: {
12731 ExternalIntArray* array = ExternalIntArray::cast(elements()); 12756 Handle<ExternalIntArray> array(
12732 return array->SetValue(index, value); 12757 ExternalIntArray::cast(object->elements()));
12758 return ExternalIntArray::SetValue(array, index, value);
12733 } 12759 }
12734 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { 12760 case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
12735 ExternalUnsignedIntArray* array = 12761 Handle<ExternalUnsignedIntArray> array(
12736 ExternalUnsignedIntArray::cast(elements()); 12762 ExternalUnsignedIntArray::cast(object->elements()));
12737 return array->SetValue(index, value); 12763 return ExternalUnsignedIntArray::SetValue(array, index, value);
12738 } 12764 }
12739 case EXTERNAL_FLOAT_ELEMENTS: { 12765 case EXTERNAL_FLOAT_ELEMENTS: {
12740 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); 12766 Handle<ExternalFloatArray> array(
12741 return array->SetValue(index, value); 12767 ExternalFloatArray::cast(object->elements()));
12768 return ExternalFloatArray::SetValue(array, index, value);
12742 } 12769 }
12743 case EXTERNAL_DOUBLE_ELEMENTS: { 12770 case EXTERNAL_DOUBLE_ELEMENTS: {
12744 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); 12771 Handle<ExternalDoubleArray> array(
12745 return array->SetValue(index, value); 12772 ExternalDoubleArray::cast(object->elements()));
12773 return ExternalDoubleArray::SetValue(array, index, value);
12746 } 12774 }
12747 case DICTIONARY_ELEMENTS: 12775 case DICTIONARY_ELEMENTS:
12748 return SetDictionaryElement(index, value, attr, strict_mode, 12776 return SetDictionaryElement(object, index, value, attributes, strict_mode,
12749 check_prototype, set_mode); 12777 check_prototype,
12778 set_mode);
12750 case NON_STRICT_ARGUMENTS_ELEMENTS: { 12779 case NON_STRICT_ARGUMENTS_ELEMENTS: {
12751 FixedArray* parameter_map = FixedArray::cast(elements()); 12780 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
12752 uint32_t length = parameter_map->length(); 12781 uint32_t length = parameter_map->length();
12753 Object* probe = 12782 Handle<Object> probe = index < length - 2 ?
12754 (index < length - 2) ? parameter_map->get(index + 2) : NULL; 12783 Handle<Object>(parameter_map->get(index + 2), isolate) :
12755 if (probe != NULL && !probe->IsTheHole()) { 12784 Handle<Object>();
12756 Context* context = Context::cast(parameter_map->get(0)); 12785 if (!probe.is_null() && !probe->IsTheHole()) {
12757 int context_index = Smi::cast(probe)->value(); 12786 Handle<Context> context(Context::cast(parameter_map->get(0)));
12787 int context_index = Handle<Smi>::cast(probe)->value();
12758 ASSERT(!context->get(context_index)->IsTheHole()); 12788 ASSERT(!context->get(context_index)->IsTheHole());
12759 context->set(context_index, value); 12789 context->set(context_index, *value);
12760 // Redefining attributes of an aliased element destroys fast aliasing. 12790 // Redefining attributes of an aliased element destroys fast aliasing.
12761 if (set_mode == SET_PROPERTY || attr == NONE) return value; 12791 if (set_mode == SET_PROPERTY || attributes == NONE) return value;
12762 parameter_map->set_the_hole(index + 2); 12792 parameter_map->set_the_hole(index + 2);
12763 // For elements that are still writable we re-establish slow aliasing. 12793 // For elements that are still writable we re-establish slow aliasing.
12764 if ((attr & READ_ONLY) == 0) { 12794 if ((attributes & READ_ONLY) == 0) {
12765 MaybeObject* maybe_entry = 12795 value = Handle<Object>::cast(
12766 isolate->heap()->AllocateAliasedArgumentsEntry(context_index); 12796 isolate->factory()->NewAliasedArgumentsEntry(context_index));
12767 if (!maybe_entry->ToObject(&value)) return maybe_entry;
12768 } 12797 }
12769 } 12798 }
12770 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 12799 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
12771 if (arguments->IsDictionary()) { 12800 if (arguments->IsDictionary()) {
12772 return SetDictionaryElement(index, value, attr, strict_mode, 12801 return SetDictionaryElement(object, index, value, attributes,
12773 check_prototype, set_mode); 12802 strict_mode,
12803 check_prototype,
12804 set_mode);
12774 } else { 12805 } else {
12775 return SetFastElement(index, value, strict_mode, check_prototype); 12806 return SetFastElement(object, index, value, strict_mode,
12807 check_prototype);
12776 } 12808 }
12777 } 12809 }
12778 } 12810 }
12779 // All possible cases have been handled above. Add a return to avoid the 12811 // All possible cases have been handled above. Add a return to avoid the
12780 // complaints from the compiler. 12812 // complaints from the compiler.
12781 UNREACHABLE(); 12813 UNREACHABLE();
12782 return isolate->heap()->null_value(); 12814 return isolate->factory()->null_value();
12783 } 12815 }
12784 12816
12785 12817
12786 void JSObject::TransitionElementsKind(Handle<JSObject> object, 12818 void JSObject::TransitionElementsKind(Handle<JSObject> object,
12787 ElementsKind to_kind) { 12819 ElementsKind to_kind) {
12788 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), 12820 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
12789 object->TransitionElementsKind(to_kind)); 12821 object->TransitionElementsKind(to_kind));
12790 } 12822 }
12791 12823
12792 12824
12793 bool AllocationSite::IsNestedSite() { 12825 bool AllocationSite::IsNestedSite() {
12794 ASSERT(FLAG_trace_track_allocation_sites); 12826 ASSERT(FLAG_trace_track_allocation_sites);
12795 Object* current = GetHeap()->allocation_sites_list(); 12827 Object* current = GetHeap()->allocation_sites_list();
12796 while (current != NULL && current->IsAllocationSite()) { 12828 while (current != NULL && current->IsAllocationSite()) {
12797 AllocationSite* current_site = AllocationSite::cast(current); 12829 AllocationSite* current_site = AllocationSite::cast(current);
12798 if (current_site->nested_site() == this) { 12830 if (current_site->nested_site() == this) {
12799 return true; 12831 return true;
12800 } 12832 }
12801 current = current_site->weak_next(); 12833 current = current_site->weak_next();
12802 } 12834 }
12803 return false; 12835 return false;
12804 } 12836 }
12805 12837
12806 12838
12807 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { 12839 MaybeObject* AllocationSite::DigestTransitionFeedback(ElementsKind to_kind) {
12808 if (!FLAG_track_allocation_sites || !IsJSArray()) { 12840 Isolate* isolate = GetIsolate();
12809 return this;
12810 }
12811 12841
12812 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); 12842 if (SitePointsToLiteral() && transition_info()->IsJSArray()) {
12813 if (memento == NULL || !memento->IsValid()) { 12843 JSArray* transition_info = JSArray::cast(this->transition_info());
12814 return this;
12815 }
12816
12817 // Walk through to the Allocation Site
12818 AllocationSite* site = memento->GetAllocationSite();
12819 if (site->SitePointsToLiteral() &&
12820 site->transition_info()->IsJSArray()) {
12821 JSArray* transition_info = JSArray::cast(site->transition_info());
12822 ElementsKind kind = transition_info->GetElementsKind(); 12844 ElementsKind kind = transition_info->GetElementsKind();
12823 // if kind is holey ensure that to_kind is as well. 12845 // if kind is holey ensure that to_kind is as well.
12824 if (IsHoleyElementsKind(kind)) { 12846 if (IsHoleyElementsKind(kind)) {
12825 to_kind = GetHoleyElementsKind(to_kind); 12847 to_kind = GetHoleyElementsKind(to_kind);
12826 } 12848 }
12827 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { 12849 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12828 // If the array is huge, it's not likely to be defined in a local 12850 // If the array is huge, it's not likely to be defined in a local
12829 // function, so we shouldn't make new instances of it very often. 12851 // function, so we shouldn't make new instances of it very often.
12830 uint32_t length = 0; 12852 uint32_t length = 0;
12831 CHECK(transition_info->length()->ToArrayIndex(&length)); 12853 CHECK(transition_info->length()->ToArrayIndex(&length));
12832 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { 12854 if (length <= kMaximumArrayBytesToPretransition) {
12833 if (FLAG_trace_track_allocation_sites) { 12855 if (FLAG_trace_track_allocation_sites) {
12834 bool is_nested = site->IsNestedSite(); 12856 bool is_nested = IsNestedSite();
12835 PrintF( 12857 PrintF(
12836 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n", 12858 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
12837 reinterpret_cast<void*>(this), 12859 reinterpret_cast<void*>(this),
12838 is_nested ? "(nested)" : "", 12860 is_nested ? "(nested)" : "",
12839 ElementsKindToString(kind), 12861 ElementsKindToString(kind),
12840 ElementsKindToString(to_kind)); 12862 ElementsKindToString(to_kind));
12841 } 12863 }
12842 return transition_info->TransitionElementsKind(to_kind); 12864 MaybeObject* result = transition_info->TransitionElementsKind(to_kind);
12865 if (result->IsFailure()) return result;
12866 dependent_code()->DeoptimizeDependentCodeGroup(
12867 isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
12843 } 12868 }
12844 } 12869 }
12845 } else { 12870 } else {
12846 ElementsKind kind = site->GetElementsKind(); 12871 ElementsKind kind = GetElementsKind();
12847 // if kind is holey ensure that to_kind is as well. 12872 // if kind is holey ensure that to_kind is as well.
12848 if (IsHoleyElementsKind(kind)) { 12873 if (IsHoleyElementsKind(kind)) {
12849 to_kind = GetHoleyElementsKind(to_kind); 12874 to_kind = GetHoleyElementsKind(to_kind);
12850 } 12875 }
12851 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { 12876 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12852 if (FLAG_trace_track_allocation_sites) { 12877 if (FLAG_trace_track_allocation_sites) {
12853 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", 12878 PrintF("AllocationSite: JSArray %p site updated %s->%s\n",
12854 reinterpret_cast<void*>(this), 12879 reinterpret_cast<void*>(this),
12855 ElementsKindToString(kind), 12880 ElementsKindToString(kind),
12856 ElementsKindToString(to_kind)); 12881 ElementsKindToString(to_kind));
12857 } 12882 }
12858 site->set_transition_info(Smi::FromInt(to_kind)); 12883 SetElementsKind(to_kind);
12884 dependent_code()->DeoptimizeDependentCodeGroup(
12885 isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
12859 } 12886 }
12860 } 12887 }
12861 return this; 12888 return this;
12862 } 12889 }
12863 12890
12864 12891
12892 void AllocationSite::AddDependentCompilationInfo(Reason reason,
12893 CompilationInfo* info) {
12894 DependentCode::DependencyGroup group = ToDependencyGroup(reason);
12895 Handle<DependentCode> dep(dependent_code());
12896 Handle<DependentCode> codes =
12897 DependentCode::Insert(dep, group, info->object_wrapper());
12898 if (*codes != dependent_code()) set_dependent_code(*codes);
12899 info->dependencies(group)->Add(Handle<HeapObject>(this), info->zone());
12900 }
12901
12902
12903 void AllocationSite::AddDependentCode(Reason reason, Handle<Code> code) {
12904 DependentCode::DependencyGroup group = ToDependencyGroup(reason);
12905 Handle<DependentCode> codes = DependentCode::Insert(
12906 Handle<DependentCode>(dependent_code()), group, code);
12907 if (*codes != dependent_code()) set_dependent_code(*codes);
12908 }
12909
12910
12911 void JSObject::UpdateAllocationSite(Handle<JSObject> object,
12912 ElementsKind to_kind) {
12913 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
12914 object->UpdateAllocationSite(to_kind));
12915 }
12916
12917
12918 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) {
12919 if (!FLAG_track_allocation_sites || !IsJSArray()) {
12920 return this;
12921 }
12922
12923 AllocationMemento* memento = AllocationMemento::FindForJSObject(this);
12924 if (memento == NULL || !memento->IsValid()) {
12925 return this;
12926 }
12927
12928 // Walk through to the Allocation Site
12929 AllocationSite* site = memento->GetAllocationSite();
12930 return site->DigestTransitionFeedback(to_kind);
12931 }
12932
12933
12865 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { 12934 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
12866 ASSERT(!map()->is_observed());
12867 ElementsKind from_kind = map()->elements_kind(); 12935 ElementsKind from_kind = map()->elements_kind();
12868 12936
12869 if (IsFastHoleyElementsKind(from_kind)) { 12937 if (IsFastHoleyElementsKind(from_kind)) {
12870 to_kind = GetHoleyElementsKind(to_kind); 12938 to_kind = GetHoleyElementsKind(to_kind);
12871 } 12939 }
12872 12940
12873 if (from_kind == to_kind) return this; 12941 if (from_kind == to_kind) return this;
12874 // Don't update the site if to_kind isn't fast 12942 // Don't update the site if to_kind isn't fast
12875 if (IsFastElementsKind(to_kind)) { 12943 if (IsFastElementsKind(to_kind)) {
12876 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); 12944 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
12944 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) { 13012 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
12945 return false; 13013 return false;
12946 } 13014 }
12947 13015
12948 // Transitions from HOLEY -> PACKED are not allowed. 13016 // Transitions from HOLEY -> PACKED are not allowed.
12949 return !IsFastHoleyElementsKind(from_kind) || 13017 return !IsFastHoleyElementsKind(from_kind) ||
12950 IsFastHoleyElementsKind(to_kind); 13018 IsFastHoleyElementsKind(to_kind);
12951 } 13019 }
12952 13020
12953 13021
13022 void JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array,
13023 uint32_t index,
13024 Handle<Object> value) {
13025 CALL_HEAP_FUNCTION_VOID(array->GetIsolate(),
13026 array->JSArrayUpdateLengthFromIndex(index, *value));
13027 }
13028
13029
12954 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, 13030 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index,
12955 Object* value) { 13031 Object* value) {
12956 uint32_t old_len = 0; 13032 uint32_t old_len = 0;
12957 CHECK(length()->ToArrayIndex(&old_len)); 13033 CHECK(length()->ToArrayIndex(&old_len));
12958 // Check to see if we need to update the length. For now, we make 13034 // Check to see if we need to update the length. For now, we make
12959 // sure that the length stays within 32-bits (unsigned). 13035 // sure that the length stays within 32-bits (unsigned).
12960 if (index >= old_len && index != 0xffffffff) { 13036 if (index >= old_len && index != 0xffffffff) {
12961 Object* len; 13037 Object* len;
12962 { MaybeObject* maybe_len = 13038 { MaybeObject* maybe_len =
12963 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); 13039 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
13049 // Fall through if packing is not guaranteed. 13125 // Fall through if packing is not guaranteed.
13050 case FAST_HOLEY_SMI_ELEMENTS: 13126 case FAST_HOLEY_SMI_ELEMENTS:
13051 case FAST_HOLEY_ELEMENTS: 13127 case FAST_HOLEY_ELEMENTS:
13052 backing_store = FixedArray::cast(backing_store_base); 13128 backing_store = FixedArray::cast(backing_store_base);
13053 *capacity = backing_store->length(); 13129 *capacity = backing_store->length();
13054 for (int i = 0; i < *capacity; ++i) { 13130 for (int i = 0; i < *capacity; ++i) {
13055 if (!backing_store->get(i)->IsTheHole()) ++(*used); 13131 if (!backing_store->get(i)->IsTheHole()) ++(*used);
13056 } 13132 }
13057 break; 13133 break;
13058 case DICTIONARY_ELEMENTS: { 13134 case DICTIONARY_ELEMENTS: {
13059 SeededNumberDictionary* dictionary = 13135 SeededNumberDictionary* dictionary = element_dictionary();
13060 SeededNumberDictionary::cast(FixedArray::cast(elements()));
13061 *capacity = dictionary->Capacity(); 13136 *capacity = dictionary->Capacity();
13062 *used = dictionary->NumberOfElements(); 13137 *used = dictionary->NumberOfElements();
13063 break; 13138 break;
13064 } 13139 }
13065 case FAST_DOUBLE_ELEMENTS: 13140 case FAST_DOUBLE_ELEMENTS:
13066 if (IsJSArray()) { 13141 if (IsJSArray()) {
13067 *capacity = backing_store_base->length(); 13142 *capacity = backing_store_base->length();
13068 *used = Smi::cast(JSArray::cast(this)->length())->value(); 13143 *used = Smi::cast(JSArray::cast(this)->length())->value();
13069 break; 13144 break;
13070 } 13145 }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
13149 SeededNumberDictionary::kEntrySize; 13224 SeededNumberDictionary::kEntrySize;
13150 return 2 * dictionary_size >= array_size; 13225 return 2 * dictionary_size >= array_size;
13151 } 13226 }
13152 13227
13153 13228
13154 bool JSObject::ShouldConvertToFastDoubleElements( 13229 bool JSObject::ShouldConvertToFastDoubleElements(
13155 bool* has_smi_only_elements) { 13230 bool* has_smi_only_elements) {
13156 *has_smi_only_elements = false; 13231 *has_smi_only_elements = false;
13157 if (FLAG_unbox_double_arrays) { 13232 if (FLAG_unbox_double_arrays) {
13158 ASSERT(HasDictionaryElements()); 13233 ASSERT(HasDictionaryElements());
13159 SeededNumberDictionary* dictionary = 13234 SeededNumberDictionary* dictionary = element_dictionary();
13160 SeededNumberDictionary::cast(elements());
13161 bool found_double = false; 13235 bool found_double = false;
13162 for (int i = 0; i < dictionary->Capacity(); i++) { 13236 for (int i = 0; i < dictionary->Capacity(); i++) {
13163 Object* key = dictionary->KeyAt(i); 13237 Object* key = dictionary->KeyAt(i);
13164 if (key->IsNumber()) { 13238 if (key->IsNumber()) {
13165 Object* value = dictionary->ValueAt(i); 13239 Object* value = dictionary->ValueAt(i);
13166 if (!value->IsNumber()) return false; 13240 if (!value->IsNumber()) return false;
13167 if (!value->IsSmi()) { 13241 if (!value->IsSmi()) {
13168 found_double = true; 13242 found_double = true;
13169 } 13243 }
13170 } 13244 }
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
13372 return result.IsPropertyCallbacks(); 13446 return result.IsPropertyCallbacks();
13373 } 13447 }
13374 13448
13375 13449
13376 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { 13450 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
13377 if (HasFastProperties()) { 13451 if (HasFastProperties()) {
13378 Map* map = this->map(); 13452 Map* map = this->map();
13379 if (filter == NONE) return map->NumberOfOwnDescriptors(); 13453 if (filter == NONE) return map->NumberOfOwnDescriptors();
13380 if (filter & DONT_ENUM) { 13454 if (filter & DONT_ENUM) {
13381 int result = map->EnumLength(); 13455 int result = map->EnumLength();
13382 if (result != Map::kInvalidEnumCache) return result; 13456 if (result != kInvalidEnumCacheSentinel) return result;
13383 } 13457 }
13384 return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter); 13458 return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter);
13385 } 13459 }
13386 return property_dictionary()->NumberOfElementsFilterAttributes(filter); 13460 return property_dictionary()->NumberOfElementsFilterAttributes(filter);
13387 } 13461 }
13388 13462
13389 13463
13390 void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) { 13464 void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) {
13391 Object* temp = get(i); 13465 Object* temp = get(i);
13392 set(i, get(j)); 13466 set(i, get(j));
(...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after
14528 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); 14602 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure);
14529 dict->CopyValuesTo(*fast_elements); 14603 dict->CopyValuesTo(*fast_elements);
14530 object->ValidateElements(); 14604 object->ValidateElements();
14531 14605
14532 object->set_map_and_elements(*new_map, *fast_elements); 14606 object->set_map_and_elements(*new_map, *fast_elements);
14533 } else if (object->HasExternalArrayElements()) { 14607 } else if (object->HasExternalArrayElements()) {
14534 // External arrays cannot have holes or undefined elements. 14608 // External arrays cannot have holes or undefined elements.
14535 return handle(Smi::FromInt( 14609 return handle(Smi::FromInt(
14536 ExternalArray::cast(object->elements())->length()), isolate); 14610 ExternalArray::cast(object->elements())->length()), isolate);
14537 } else if (!object->HasFastDoubleElements()) { 14611 } else if (!object->HasFastDoubleElements()) {
14538 JSObject::EnsureWritableFastElements(object); 14612 EnsureWritableFastElements(object);
14539 } 14613 }
14540 ASSERT(object->HasFastSmiOrObjectElements() || 14614 ASSERT(object->HasFastSmiOrObjectElements() ||
14541 object->HasFastDoubleElements()); 14615 object->HasFastDoubleElements());
14542 14616
14543 // Collect holes at the end, undefined before that and the rest at the 14617 // Collect holes at the end, undefined before that and the rest at the
14544 // start, and return the number of non-hole, non-undefined values. 14618 // start, and return the number of non-hole, non-undefined values.
14545 14619
14546 Handle<FixedArrayBase> elements_base(object->elements()); 14620 Handle<FixedArrayBase> elements_base(object->elements());
14547 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); 14621 uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
14548 if (limit > elements_length) { 14622 if (limit > elements_length) {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
14735 // Clamp undefined to zero (default). All other types have been 14809 // Clamp undefined to zero (default). All other types have been
14736 // converted to a number type further up in the call chain. 14810 // converted to a number type further up in the call chain.
14737 ASSERT(value->IsUndefined()); 14811 ASSERT(value->IsUndefined());
14738 } 14812 }
14739 receiver->set(index, cast_value); 14813 receiver->set(index, cast_value);
14740 } 14814 }
14741 return heap->NumberFromInt32(cast_value); 14815 return heap->NumberFromInt32(cast_value);
14742 } 14816 }
14743 14817
14744 14818
14819 Handle<Object> ExternalByteArray::SetValue(Handle<ExternalByteArray> array,
14820 uint32_t index,
14821 Handle<Object> value) {
14822 CALL_HEAP_FUNCTION(array->GetIsolate(),
14823 array->SetValue(index, *value),
14824 Object);
14825 }
14826
14827
14745 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { 14828 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) {
14746 return ExternalArrayIntSetter<ExternalByteArray, int8_t> 14829 return ExternalArrayIntSetter<ExternalByteArray, int8_t>
14747 (GetHeap(), this, index, value); 14830 (GetHeap(), this, index, value);
14748 } 14831 }
14749 14832
14750 14833
14834 Handle<Object> ExternalUnsignedByteArray::SetValue(
14835 Handle<ExternalUnsignedByteArray> array,
14836 uint32_t index,
14837 Handle<Object> value) {
14838 CALL_HEAP_FUNCTION(array->GetIsolate(),
14839 array->SetValue(index, *value),
14840 Object);
14841 }
14842
14843
14751 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, 14844 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index,
14752 Object* value) { 14845 Object* value) {
14753 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> 14846 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t>
14754 (GetHeap(), this, index, value); 14847 (GetHeap(), this, index, value);
14755 } 14848 }
14756 14849
14757 14850
14851 Handle<Object> ExternalShortArray::SetValue(
14852 Handle<ExternalShortArray> array,
14853 uint32_t index,
14854 Handle<Object> value) {
14855 CALL_HEAP_FUNCTION(array->GetIsolate(),
14856 array->SetValue(index, *value),
14857 Object);
14858 }
14859
14860
14758 MaybeObject* ExternalShortArray::SetValue(uint32_t index, 14861 MaybeObject* ExternalShortArray::SetValue(uint32_t index,
14759 Object* value) { 14862 Object* value) {
14760 return ExternalArrayIntSetter<ExternalShortArray, int16_t> 14863 return ExternalArrayIntSetter<ExternalShortArray, int16_t>
14761 (GetHeap(), this, index, value); 14864 (GetHeap(), this, index, value);
14762 } 14865 }
14763 14866
14764 14867
14868 Handle<Object> ExternalUnsignedShortArray::SetValue(
14869 Handle<ExternalUnsignedShortArray> array,
14870 uint32_t index,
14871 Handle<Object> value) {
14872 CALL_HEAP_FUNCTION(array->GetIsolate(),
14873 array->SetValue(index, *value),
14874 Object);
14875 }
14876
14877
14765 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, 14878 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index,
14766 Object* value) { 14879 Object* value) {
14767 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> 14880 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t>
14768 (GetHeap(), this, index, value); 14881 (GetHeap(), this, index, value);
14769 } 14882 }
14770 14883
14771 14884
14885 Handle<Object> ExternalIntArray::SetValue(Handle<ExternalIntArray> array,
14886 uint32_t index,
14887 Handle<Object> value) {
14888 CALL_HEAP_FUNCTION(array->GetIsolate(),
14889 array->SetValue(index, *value),
14890 Object);
14891 }
14892
14893
14772 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { 14894 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) {
14773 return ExternalArrayIntSetter<ExternalIntArray, int32_t> 14895 return ExternalArrayIntSetter<ExternalIntArray, int32_t>
14774 (GetHeap(), this, index, value); 14896 (GetHeap(), this, index, value);
14775 } 14897 }
14776 14898
14777 14899
14900 Handle<Object> ExternalUnsignedIntArray::SetValue(
14901 Handle<ExternalUnsignedIntArray> array,
14902 uint32_t index,
14903 Handle<Object> value) {
14904 CALL_HEAP_FUNCTION(array->GetIsolate(),
14905 array->SetValue(index, *value),
14906 Object);
14907 }
14908
14909
14778 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { 14910 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) {
14779 uint32_t cast_value = 0; 14911 uint32_t cast_value = 0;
14780 Heap* heap = GetHeap(); 14912 Heap* heap = GetHeap();
14781 if (index < static_cast<uint32_t>(length())) { 14913 if (index < static_cast<uint32_t>(length())) {
14782 if (value->IsSmi()) { 14914 if (value->IsSmi()) {
14783 int int_value = Smi::cast(value)->value(); 14915 int int_value = Smi::cast(value)->value();
14784 cast_value = static_cast<uint32_t>(int_value); 14916 cast_value = static_cast<uint32_t>(int_value);
14785 } else if (value->IsHeapNumber()) { 14917 } else if (value->IsHeapNumber()) {
14786 double double_value = HeapNumber::cast(value)->value(); 14918 double double_value = HeapNumber::cast(value)->value();
14787 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); 14919 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value));
14788 } else { 14920 } else {
14789 // Clamp undefined to zero (default). All other types have been 14921 // Clamp undefined to zero (default). All other types have been
14790 // converted to a number type further up in the call chain. 14922 // converted to a number type further up in the call chain.
14791 ASSERT(value->IsUndefined()); 14923 ASSERT(value->IsUndefined());
14792 } 14924 }
14793 set(index, cast_value); 14925 set(index, cast_value);
14794 } 14926 }
14795 return heap->NumberFromUint32(cast_value); 14927 return heap->NumberFromUint32(cast_value);
14796 } 14928 }
14797 14929
14798 14930
14931 Handle<Object> ExternalFloatArray::SetValue(Handle<ExternalFloatArray> array,
14932 uint32_t index,
14933 Handle<Object> value) {
14934 CALL_HEAP_FUNCTION(array->GetIsolate(),
14935 array->SetValue(index, *value),
14936 Object);
14937 }
14938
14939
14799 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { 14940 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) {
14800 float cast_value = static_cast<float>(OS::nan_value()); 14941 float cast_value = static_cast<float>(OS::nan_value());
14801 Heap* heap = GetHeap(); 14942 Heap* heap = GetHeap();
14802 if (index < static_cast<uint32_t>(length())) { 14943 if (index < static_cast<uint32_t>(length())) {
14803 if (value->IsSmi()) { 14944 if (value->IsSmi()) {
14804 int int_value = Smi::cast(value)->value(); 14945 int int_value = Smi::cast(value)->value();
14805 cast_value = static_cast<float>(int_value); 14946 cast_value = static_cast<float>(int_value);
14806 } else if (value->IsHeapNumber()) { 14947 } else if (value->IsHeapNumber()) {
14807 double double_value = HeapNumber::cast(value)->value(); 14948 double double_value = HeapNumber::cast(value)->value();
14808 cast_value = static_cast<float>(double_value); 14949 cast_value = static_cast<float>(double_value);
14809 } else { 14950 } else {
14810 // Clamp undefined to NaN (default). All other types have been 14951 // Clamp undefined to NaN (default). All other types have been
14811 // converted to a number type further up in the call chain. 14952 // converted to a number type further up in the call chain.
14812 ASSERT(value->IsUndefined()); 14953 ASSERT(value->IsUndefined());
14813 } 14954 }
14814 set(index, cast_value); 14955 set(index, cast_value);
14815 } 14956 }
14816 return heap->AllocateHeapNumber(cast_value); 14957 return heap->AllocateHeapNumber(cast_value);
14817 } 14958 }
14818 14959
14819 14960
14961 Handle<Object> ExternalDoubleArray::SetValue(Handle<ExternalDoubleArray> array,
14962 uint32_t index,
14963 Handle<Object> value) {
14964 CALL_HEAP_FUNCTION(array->GetIsolate(),
14965 array->SetValue(index, *value),
14966 Object);
14967 }
14968
14969
14820 MaybeObject* ExternalDoubleArray::SetValue(uint32_t index, Object* value) { 14970 MaybeObject* ExternalDoubleArray::SetValue(uint32_t index, Object* value) {
14821 double double_value = OS::nan_value(); 14971 double double_value = OS::nan_value();
14822 Heap* heap = GetHeap(); 14972 Heap* heap = GetHeap();
14823 if (index < static_cast<uint32_t>(length())) { 14973 if (index < static_cast<uint32_t>(length())) {
14824 if (value->IsSmi()) { 14974 if (value->IsSmi()) {
14825 int int_value = Smi::cast(value)->value(); 14975 int int_value = Smi::cast(value)->value();
14826 double_value = static_cast<double>(int_value); 14976 double_value = static_cast<double>(int_value);
14827 } else if (value->IsHeapNumber()) { 14977 } else if (value->IsHeapNumber()) {
14828 double_value = HeapNumber::cast(value)->value(); 14978 double_value = HeapNumber::cast(value)->value();
14829 } else { 14979 } else {
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
15431 return; 15581 return;
15432 } 15582 }
15433 // Update max key value. 15583 // Update max key value.
15434 Object* max_index_object = get(kMaxNumberKeyIndex); 15584 Object* max_index_object = get(kMaxNumberKeyIndex);
15435 if (!max_index_object->IsSmi() || max_number_key() < key) { 15585 if (!max_index_object->IsSmi() || max_number_key() < key) {
15436 FixedArray::set(kMaxNumberKeyIndex, 15586 FixedArray::set(kMaxNumberKeyIndex,
15437 Smi::FromInt(key << kRequiresSlowElementsTagSize)); 15587 Smi::FromInt(key << kRequiresSlowElementsTagSize));
15438 } 15588 }
15439 } 15589 }
15440 15590
15591 Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry(
15592 Handle<SeededNumberDictionary> dictionary,
15593 uint32_t key,
15594 Handle<Object> value,
15595 PropertyDetails details) {
15596 CALL_HEAP_FUNCTION(dictionary->GetIsolate(),
15597 dictionary->AddNumberEntry(key, *value, details),
15598 SeededNumberDictionary);
15599 }
15441 15600
15442 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key, 15601 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key,
15443 Object* value, 15602 Object* value,
15444 PropertyDetails details) { 15603 PropertyDetails details) {
15445 UpdateMaxNumberKey(key); 15604 UpdateMaxNumberKey(key);
15446 SLOW_ASSERT(this->FindEntry(key) == kNotFound); 15605 SLOW_ASSERT(this->FindEntry(key) == kNotFound);
15447 return Add(key, value, details); 15606 return Add(key, value, details);
15448 } 15607 }
15449 15608
15450 15609
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
15654 Heap* heap = Dictionary<Shape, Key>::GetHeap(); 15813 Heap* heap = Dictionary<Shape, Key>::GetHeap();
15655 return heap->undefined_value(); 15814 return heap->undefined_value();
15656 } 15815 }
15657 15816
15658 15817
15659 MaybeObject* NameDictionary::TransformPropertiesToFastFor( 15818 MaybeObject* NameDictionary::TransformPropertiesToFastFor(
15660 JSObject* obj, int unused_property_fields) { 15819 JSObject* obj, int unused_property_fields) {
15661 // Make sure we preserve dictionary representation if there are too many 15820 // Make sure we preserve dictionary representation if there are too many
15662 // descriptors. 15821 // descriptors.
15663 int number_of_elements = NumberOfElements(); 15822 int number_of_elements = NumberOfElements();
15664 if (number_of_elements > DescriptorArray::kMaxNumberOfDescriptors) return obj; 15823 if (number_of_elements > kMaxNumberOfDescriptors) return obj;
15665 15824
15666 if (number_of_elements != NextEnumerationIndex()) { 15825 if (number_of_elements != NextEnumerationIndex()) {
15667 MaybeObject* maybe_result = GenerateNewEnumerationIndices(); 15826 MaybeObject* maybe_result = GenerateNewEnumerationIndices();
15668 if (maybe_result->IsFailure()) return maybe_result; 15827 if (maybe_result->IsFailure()) return maybe_result;
15669 } 15828 }
15670 15829
15671 int instance_descriptor_length = 0; 15830 int instance_descriptor_length = 0;
15672 int number_of_fields = 0; 15831 int number_of_fields = 0;
15673 15832
15674 Heap* heap = GetHeap(); 15833 Heap* heap = GetHeap();
(...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after
16526 #define ERROR_MESSAGES_TEXTS(C, T) T, 16685 #define ERROR_MESSAGES_TEXTS(C, T) T,
16527 static const char* error_messages_[] = { 16686 static const char* error_messages_[] = {
16528 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16687 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16529 }; 16688 };
16530 #undef ERROR_MESSAGES_TEXTS 16689 #undef ERROR_MESSAGES_TEXTS
16531 return error_messages_[reason]; 16690 return error_messages_[reason];
16532 } 16691 }
16533 16692
16534 16693
16535 } } // namespace v8::internal 16694 } } // namespace v8::internal
OLDNEW
« include/v8-platform.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