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

Side by Side Diff: src/objects.cc

Issue 7535004: Merge bleeding edge up to 8774 into the GC branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 #endif 53 #endif
54 54
55 namespace v8 { 55 namespace v8 {
56 namespace internal { 56 namespace internal {
57 57
58 // Getters and setters are stored in a fixed array property. These are 58 // Getters and setters are stored in a fixed array property. These are
59 // constants for their indices. 59 // constants for their indices.
60 const int kGetterIndex = 0; 60 const int kGetterIndex = 0;
61 const int kSetterIndex = 1; 61 const int kSetterIndex = 1;
62 62
63 uint64_t FixedDoubleArray::kHoleNanInt64 = -1;
64 uint64_t FixedDoubleArray::kCanonicalNonHoleNanLower32 = 0x7FF00000;
65 uint64_t FixedDoubleArray::kCanonicalNonHoleNanInt64 =
66 kCanonicalNonHoleNanLower32 << 32;
67
68 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, 63 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
69 Object* value) { 64 Object* value) {
70 Object* result; 65 Object* result;
71 { MaybeObject* maybe_result = 66 { MaybeObject* maybe_result =
72 constructor->GetHeap()->AllocateJSObject(constructor); 67 constructor->GetHeap()->AllocateJSObject(constructor);
73 if (!maybe_result->ToObject(&result)) return maybe_result; 68 if (!maybe_result->ToObject(&result)) return maybe_result;
74 } 69 }
75 JSValue::cast(result)->set_value(value); 70 JSValue::cast(result)->set_value(value);
76 return result; 71 return result;
77 } 72 }
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 MaybeObject* value = (callback->getter)(receiver, callback->data); 184 MaybeObject* value = (callback->getter)(receiver, callback->data);
190 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 185 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
191 return value; 186 return value;
192 } 187 }
193 188
194 // api style callbacks. 189 // api style callbacks.
195 if (structure->IsAccessorInfo()) { 190 if (structure->IsAccessorInfo()) {
196 AccessorInfo* data = AccessorInfo::cast(structure); 191 AccessorInfo* data = AccessorInfo::cast(structure);
197 Object* fun_obj = data->getter(); 192 Object* fun_obj = data->getter();
198 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); 193 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
199 HandleScope scope; 194 HandleScope scope(isolate);
200 JSObject* self = JSObject::cast(receiver); 195 JSObject* self = JSObject::cast(receiver);
201 JSObject* holder_handle = JSObject::cast(holder); 196 JSObject* holder_handle = JSObject::cast(holder);
202 Handle<String> key(name); 197 Handle<String> key(name);
203 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); 198 LOG(isolate, ApiNamedPropertyAccess("load", self, name));
204 CustomArguments args(isolate, data->data(), self, holder_handle); 199 CustomArguments args(isolate, data->data(), self, holder_handle);
205 v8::AccessorInfo info(args.end()); 200 v8::AccessorInfo info(args.end());
206 v8::Handle<v8::Value> result; 201 v8::Handle<v8::Value> result;
207 { 202 {
208 // Leaving JavaScript. 203 // Leaving JavaScript.
209 VMState state(isolate, EXTERNAL); 204 VMState state(isolate, EXTERNAL);
(...skipping 19 matching lines...) Expand all
229 224
230 UNREACHABLE(); 225 UNREACHABLE();
231 return NULL; 226 return NULL;
232 } 227 }
233 228
234 229
235 MaybeObject* Object::GetPropertyWithHandler(Object* receiver_raw, 230 MaybeObject* Object::GetPropertyWithHandler(Object* receiver_raw,
236 String* name_raw, 231 String* name_raw,
237 Object* handler_raw) { 232 Object* handler_raw) {
238 Isolate* isolate = name_raw->GetIsolate(); 233 Isolate* isolate = name_raw->GetIsolate();
239 HandleScope scope; 234 HandleScope scope(isolate);
240 Handle<Object> receiver(receiver_raw); 235 Handle<Object> receiver(receiver_raw);
241 Handle<Object> name(name_raw); 236 Handle<Object> name(name_raw);
242 Handle<Object> handler(handler_raw); 237 Handle<Object> handler(handler_raw);
243 238
244 // Extract trap function. 239 // Extract trap function.
245 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("get"); 240 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("get");
246 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); 241 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
247 if (trap->IsUndefined()) { 242 if (trap->IsUndefined()) {
248 // Get the derived `get' property. 243 // Get the derived `get' property.
249 trap = isolate->derived_get_trap(); 244 trap = isolate->derived_get_trap();
(...skipping 1639 matching lines...) Expand 10 before | Expand all | Expand 10 after
1889 1884
1890 1885
1891 void JSObject::LookupCallbackSetterInPrototypes(String* name, 1886 void JSObject::LookupCallbackSetterInPrototypes(String* name,
1892 LookupResult* result) { 1887 LookupResult* result) {
1893 Heap* heap = GetHeap(); 1888 Heap* heap = GetHeap();
1894 for (Object* pt = GetPrototype(); 1889 for (Object* pt = GetPrototype();
1895 pt != heap->null_value(); 1890 pt != heap->null_value();
1896 pt = pt->GetPrototype()) { 1891 pt = pt->GetPrototype()) {
1897 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); 1892 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
1898 if (result->IsProperty()) { 1893 if (result->IsProperty()) {
1899 if (result->IsReadOnly()) { 1894 if (result->type() == CALLBACKS && !result->IsReadOnly()) return;
1900 result->NotFound(); 1895 // Found non-callback or read-only callback, stop looking.
1901 return; 1896 break;
1902 }
1903 if (result->type() == CALLBACKS) {
1904 return;
1905 }
1906 } 1897 }
1907 } 1898 }
1908 result->NotFound(); 1899 result->NotFound();
1909 } 1900 }
1910 1901
1911 1902
1912 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( 1903 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
1913 uint32_t index, 1904 uint32_t index,
1914 Object* value, 1905 Object* value,
1915 bool* found, 1906 bool* found,
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
2189 } 2180 }
2190 break; 2181 break;
2191 } 2182 }
2192 default: { 2183 default: {
2193 break; 2184 break;
2194 } 2185 }
2195 } 2186 }
2196 } 2187 }
2197 } 2188 }
2198 2189
2199 HandleScope scope; 2190 Heap* heap = GetHeap();
2191 HandleScope scope(heap->isolate());
2200 Handle<Object> value_handle(value); 2192 Handle<Object> value_handle(value);
2201 Heap* heap = GetHeap();
2202 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); 2193 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET);
2203 return *value_handle; 2194 return *value_handle;
2204 } 2195 }
2205 2196
2206 2197
2207 MaybeObject* JSReceiver::SetProperty(LookupResult* result, 2198 MaybeObject* JSReceiver::SetProperty(LookupResult* result,
2208 String* key, 2199 String* key,
2209 Object* value, 2200 Object* value,
2210 PropertyAttributes attributes, 2201 PropertyAttributes attributes,
2211 StrictModeFlag strict_mode) { 2202 StrictModeFlag strict_mode) {
2212 if (result->IsFound() && result->type() == HANDLER) { 2203 if (result->IsFound() && result->type() == HANDLER) {
2213 return JSProxy::cast(this)->SetPropertyWithHandler( 2204 return JSProxy::cast(this)->SetPropertyWithHandler(
2214 key, value, attributes, strict_mode); 2205 key, value, attributes, strict_mode);
2215 } else { 2206 } else {
2216 return JSObject::cast(this)->SetPropertyForResult( 2207 return JSObject::cast(this)->SetPropertyForResult(
2217 result, key, value, attributes, strict_mode); 2208 result, key, value, attributes, strict_mode);
2218 } 2209 }
2219 } 2210 }
2220 2211
2221 2212
2213 bool JSProxy::HasPropertyWithHandler(String* name_raw) {
2214 Isolate* isolate = GetIsolate();
2215 HandleScope scope(isolate);
2216 Handle<Object> receiver(this);
2217 Handle<Object> name(name_raw);
2218 Handle<Object> handler(this->handler());
2219
2220 // Extract trap function.
2221 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("has");
2222 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
2223 if (trap->IsUndefined()) {
2224 trap = isolate->derived_has_trap();
2225 }
2226
2227 // Call trap function.
2228 Object** args[] = { name.location() };
2229 bool has_exception;
2230 Handle<Object> result =
2231 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception);
2232 if (has_exception) return Failure::Exception();
2233
2234 return result->ToBoolean()->IsTrue();
2235 }
2236
2237
2222 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( 2238 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
2223 String* name_raw, 2239 String* name_raw,
2224 Object* value_raw, 2240 Object* value_raw,
2225 PropertyAttributes attributes, 2241 PropertyAttributes attributes,
2226 StrictModeFlag strict_mode) { 2242 StrictModeFlag strict_mode) {
2227 Isolate* isolate = GetIsolate(); 2243 Isolate* isolate = GetIsolate();
2228 HandleScope scope; 2244 HandleScope scope(isolate);
2229 Handle<Object> receiver(this); 2245 Handle<Object> receiver(this);
2230 Handle<Object> name(name_raw); 2246 Handle<Object> name(name_raw);
2231 Handle<Object> value(value_raw); 2247 Handle<Object> value(value_raw);
2232 Handle<Object> handler(this->handler()); 2248 Handle<Object> handler(this->handler());
2233 2249
2234 // Extract trap function. 2250 // Extract trap function.
2235 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("set"); 2251 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("set");
2236 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); 2252 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
2237 if (trap->IsUndefined()) { 2253 if (trap->IsUndefined()) {
2238 trap = isolate->derived_set_trap(); 2254 trap = isolate->derived_set_trap();
2239 } 2255 }
2240 2256
2241 // Call trap function. 2257 // Call trap function.
2242 Object** args[] = { 2258 Object** args[] = {
2243 receiver.location(), name.location(), value.location() 2259 receiver.location(), name.location(), value.location()
2244 }; 2260 };
2245 bool has_exception; 2261 bool has_exception;
2246 Handle<Object> result = 2262 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception);
2247 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception);
2248 if (has_exception) return Failure::Exception(); 2263 if (has_exception) return Failure::Exception();
2249 2264
2250 return *value; 2265 return *value;
2251 } 2266 }
2252 2267
2253 2268
2269 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler(
2270 String* name_raw, DeleteMode mode) {
2271 Isolate* isolate = GetIsolate();
2272 HandleScope scope(isolate);
2273 Handle<Object> receiver(this);
2274 Handle<Object> name(name_raw);
2275 Handle<Object> handler(this->handler());
2276
2277 // Extract trap function.
2278 Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("delete");
2279 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
2280 if (trap->IsUndefined()) {
2281 Handle<Object> args[] = { handler, trap_name };
2282 Handle<Object> error = isolate->factory()->NewTypeError(
2283 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args)));
2284 isolate->Throw(*error);
2285 return Failure::Exception();
2286 }
2287
2288 // Call trap function.
2289 Object** args[] = { name.location() };
2290 bool has_exception;
2291 Handle<Object> result =
2292 Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception);
2293 if (has_exception) return Failure::Exception();
2294
2295 Object* bool_result = result->ToBoolean();
2296 if (mode == STRICT_DELETION && bool_result == GetHeap()->false_value()) {
2297 Handle<Object> args[] = { handler, trap_name };
2298 Handle<Object> error = isolate->factory()->NewTypeError(
2299 "handler_failed", HandleVector(args, ARRAY_SIZE(args)));
2300 isolate->Throw(*error);
2301 return Failure::Exception();
2302 }
2303 return bool_result;
2304 }
2305
2306
2254 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler( 2307 MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
2255 JSReceiver* receiver_raw, 2308 JSReceiver* receiver_raw,
2256 String* name_raw, 2309 String* name_raw,
2257 bool* has_exception) { 2310 bool* has_exception) {
2258 Isolate* isolate = GetIsolate(); 2311 Isolate* isolate = GetIsolate();
2259 HandleScope scope; 2312 HandleScope scope(isolate);
2260 Handle<JSReceiver> receiver(receiver_raw); 2313 Handle<JSReceiver> receiver(receiver_raw);
2261 Handle<Object> name(name_raw); 2314 Handle<Object> name(name_raw);
2262 Handle<Object> handler(this->handler()); 2315 Handle<Object> handler(this->handler());
2263 2316
2264 // Extract trap function. 2317 // Extract trap function.
2265 Handle<String> trap_name = 2318 Handle<String> trap_name =
2266 isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor"); 2319 isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor");
2267 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name)); 2320 Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
2268 if (trap->IsUndefined()) { 2321 if (trap->IsUndefined()) {
2269 Handle<Object> args[] = { handler, trap_name }; 2322 Handle<Object> args[] = { handler, trap_name };
2270 Handle<Object> error = isolate->factory()->NewTypeError( 2323 Handle<Object> error = isolate->factory()->NewTypeError(
2271 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args))); 2324 "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args)));
2272 isolate->Throw(*error); 2325 isolate->Throw(*error);
2273 *has_exception = true; 2326 *has_exception = true;
2274 return NONE; 2327 return NONE;
2275 } 2328 }
2276 2329
2277 // Call trap function. 2330 // Call trap function.
2278 Object** args[] = { name.location() }; 2331 Object** args[] = { name.location() };
2279 Handle<Object> result = 2332 Handle<Object> result =
2280 Execution::Call(trap, handler, ARRAY_SIZE(args), args, has_exception); 2333 Execution::Call(trap, handler, ARRAY_SIZE(args), args, has_exception);
2281 if (has_exception) return NONE; 2334 if (has_exception) return NONE;
2282 2335
2283 // TODO(rossberg): convert result to PropertyAttributes 2336 // TODO(rossberg): convert result to PropertyAttributes
2284 USE(result); 2337 USE(result);
2285 return NONE; 2338 return NONE;
2286 } 2339 }
2287 2340
2288 2341
2342 void JSProxy::Fix() {
2343 Isolate* isolate = GetIsolate();
2344 HandleScope scope(isolate);
2345 Handle<JSProxy> self(this);
2346
2347 isolate->factory()->BecomeJSObject(self);
2348 ASSERT(self->IsJSObject());
2349 // TODO(rossberg): recognize function proxies.
2350 }
2351
2352
2353
2289 MaybeObject* JSObject::SetPropertyForResult(LookupResult* result, 2354 MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
2290 String* name, 2355 String* name,
2291 Object* value, 2356 Object* value,
2292 PropertyAttributes attributes, 2357 PropertyAttributes attributes,
2293 StrictModeFlag strict_mode) { 2358 StrictModeFlag strict_mode) {
2294 Heap* heap = GetHeap(); 2359 Heap* heap = GetHeap();
2295 // Make sure that the top context does not change when doing callbacks or 2360 // Make sure that the top context does not change when doing callbacks or
2296 // interceptor calls. 2361 // interceptor calls.
2297 AssertNoContextChange ncc; 2362 AssertNoContextChange ncc;
2298 2363
2299 // Optimization for 2-byte strings often used as keys in a decompression 2364 // Optimization for 2-byte strings often used as keys in a decompression
2300 // dictionary. We make these short keys into symbols to avoid constantly 2365 // dictionary. We make these short keys into symbols to avoid constantly
2301 // reallocating them. 2366 // reallocating them.
2302 if (!name->IsSymbol() && name->length() <= 2) { 2367 if (!name->IsSymbol() && name->length() <= 2) {
2303 Object* symbol_version; 2368 Object* symbol_version;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2338 accessor_result.holder(), 2403 accessor_result.holder(),
2339 strict_mode); 2404 strict_mode);
2340 } 2405 }
2341 } 2406 }
2342 if (!result->IsFound()) { 2407 if (!result->IsFound()) {
2343 // Neither properties nor transitions found. 2408 // Neither properties nor transitions found.
2344 return AddProperty(name, value, attributes, strict_mode); 2409 return AddProperty(name, value, attributes, strict_mode);
2345 } 2410 }
2346 if (result->IsReadOnly() && result->IsProperty()) { 2411 if (result->IsReadOnly() && result->IsProperty()) {
2347 if (strict_mode == kStrictMode) { 2412 if (strict_mode == kStrictMode) {
2348 HandleScope scope; 2413 HandleScope scope(heap->isolate());
2349 Handle<String> key(name); 2414 Handle<String> key(name);
2350 Handle<Object> holder(this); 2415 Handle<Object> holder(this);
2351 Handle<Object> args[2] = { key, holder }; 2416 Handle<Object> args[2] = { key, holder };
2352 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( 2417 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError(
2353 "strict_read_only_property", HandleVector(args, 2))); 2418 "strict_read_only_property", HandleVector(args, 2)));
2354 } else { 2419 } else {
2355 return value; 2420 return value;
2356 } 2421 }
2357 } 2422 }
2358 // This is a real property that is not read-only, or it is a 2423 // This is a real property that is not read-only, or it is a
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2413 return value; 2478 return value;
2414 } 2479 }
2415 2480
2416 2481
2417 // Set a real local property, even if it is READ_ONLY. If the property is not 2482 // Set a real local property, even if it is READ_ONLY. If the property is not
2418 // present, add it with attributes NONE. This code is an exact clone of 2483 // present, add it with attributes NONE. This code is an exact clone of
2419 // SetProperty, with the check for IsReadOnly and the check for a 2484 // SetProperty, with the check for IsReadOnly and the check for a
2420 // callback setter removed. The two lines looking up the LookupResult 2485 // callback setter removed. The two lines looking up the LookupResult
2421 // result are also added. If one of the functions is changed, the other 2486 // result are also added. If one of the functions is changed, the other
2422 // should be. 2487 // should be.
2488 // Note that this method cannot be used to set the prototype of a function
2489 // because ConvertDescriptorToField() which is called in "case CALLBACKS:"
2490 // doesn't handle function prototypes correctly.
2423 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( 2491 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
2424 String* name, 2492 String* name,
2425 Object* value, 2493 Object* value,
2426 PropertyAttributes attributes) { 2494 PropertyAttributes attributes) {
2427 2495
2428 // Make sure that the top context does not change when doing callbacks or 2496 // Make sure that the top context does not change when doing callbacks or
2429 // interceptor calls. 2497 // interceptor calls.
2430 AssertNoContextChange ncc; 2498 AssertNoContextChange ncc;
2431 LookupResult result; 2499 LookupResult result;
2432 LocalLookup(name, &result); 2500 LocalLookup(name, &result);
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
2826 ASSERT(!IsGlobalObject()); 2894 ASSERT(!IsGlobalObject());
2827 return property_dictionary()-> 2895 return property_dictionary()->
2828 TransformPropertiesToFastFor(this, unused_property_fields); 2896 TransformPropertiesToFastFor(this, unused_property_fields);
2829 } 2897 }
2830 2898
2831 2899
2832 MaybeObject* JSObject::NormalizeElements() { 2900 MaybeObject* JSObject::NormalizeElements() {
2833 ASSERT(!HasExternalArrayElements()); 2901 ASSERT(!HasExternalArrayElements());
2834 2902
2835 // Find the backing store. 2903 // Find the backing store.
2836 FixedArray* array = FixedArray::cast(elements()); 2904 FixedArrayBase* array = FixedArrayBase::cast(elements());
2837 Map* old_map = array->map(); 2905 Map* old_map = array->map();
2838 bool is_arguments = 2906 bool is_arguments =
2839 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); 2907 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map());
2840 if (is_arguments) { 2908 if (is_arguments) {
2841 array = FixedArray::cast(array->get(1)); 2909 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1));
2842 } 2910 }
2843 if (array->IsDictionary()) return array; 2911 if (array->IsDictionary()) return array;
2844 2912
2845 ASSERT(HasFastElements() || HasFastArgumentsElements()); 2913 ASSERT(HasFastElements() ||
2914 HasFastDoubleElements() ||
2915 HasFastArgumentsElements());
2846 // Compute the effective length and allocate a new backing store. 2916 // Compute the effective length and allocate a new backing store.
2847 int length = IsJSArray() 2917 int length = IsJSArray()
2848 ? Smi::cast(JSArray::cast(this)->length())->value() 2918 ? Smi::cast(JSArray::cast(this)->length())->value()
2849 : array->length(); 2919 : array->length();
2920 int old_capacity = 0;
2921 int used_elements = 0;
2922 GetElementsCapacityAndUsage(&old_capacity, &used_elements);
2850 NumberDictionary* dictionary = NULL; 2923 NumberDictionary* dictionary = NULL;
2851 { Object* object; 2924 { Object* object;
2852 MaybeObject* maybe = NumberDictionary::Allocate(length); 2925 MaybeObject* maybe = NumberDictionary::Allocate(used_elements);
2853 if (!maybe->ToObject(&object)) return maybe; 2926 if (!maybe->ToObject(&object)) return maybe;
2854 dictionary = NumberDictionary::cast(object); 2927 dictionary = NumberDictionary::cast(object);
2855 } 2928 }
2856 2929
2857 // Copy the elements to the new backing store. 2930 // Copy the elements to the new backing store.
2858 bool has_double_elements = old_map->has_fast_double_elements(); 2931 bool has_double_elements = array->IsFixedDoubleArray();
2859 for (int i = 0; i < length; i++) { 2932 for (int i = 0; i < length; i++) {
2860 Object* value = NULL; 2933 Object* value = NULL;
2861 if (has_double_elements) { 2934 if (has_double_elements) {
2862 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); 2935 FixedDoubleArray* double_array = FixedDoubleArray::cast(array);
2863 if (double_array->is_the_hole(i)) { 2936 if (double_array->is_the_hole(i)) {
2864 value = GetIsolate()->heap()->the_hole_value(); 2937 value = GetIsolate()->heap()->the_hole_value();
2865 } else { 2938 } else {
2866 // Objects must be allocated in the old object space, since the 2939 // Objects must be allocated in the old object space, since the
2867 // overall number of HeapNumbers needed for the conversion might 2940 // overall number of HeapNumbers needed for the conversion might
2868 // exceed the capacity of new space, and we would fail repeatedly 2941 // exceed the capacity of new space, and we would fail repeatedly
2869 // trying to convert the FixedDoubleArray. 2942 // trying to convert the FixedDoubleArray.
2870 MaybeObject* maybe_value_object = 2943 MaybeObject* maybe_value_object =
2871 GetHeap()->AllocateHeapNumber(double_array->get(i), TENURED); 2944 GetHeap()->AllocateHeapNumber(double_array->get(i), TENURED);
2872 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 2945 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
2873 } 2946 }
2874 } else { 2947 } else {
2875 ASSERT(old_map->has_fast_elements()); 2948 ASSERT(old_map->has_fast_elements());
2876 value = array->get(i); 2949 value = FixedArray::cast(array)->get(i);
2877 } 2950 }
2878 PropertyDetails details = PropertyDetails(NONE, NORMAL); 2951 PropertyDetails details = PropertyDetails(NONE, NORMAL);
2879 if (!value->IsTheHole()) { 2952 if (!value->IsTheHole()) {
2880 Object* result; 2953 Object* result;
2881 MaybeObject* maybe_result = 2954 MaybeObject* maybe_result =
2882 dictionary->AddNumberEntry(i, value, details); 2955 dictionary->AddNumberEntry(i, value, details);
2883 if (!maybe_result->ToObject(&result)) return maybe_result; 2956 if (!maybe_result->ToObject(&result)) return maybe_result;
2884 dictionary = NumberDictionary::cast(result); 2957 dictionary = NumberDictionary::cast(result);
2885 } 2958 }
2886 } 2959 }
(...skipping 19 matching lines...) Expand all
2906 PrintF("Object elements have been normalized:\n"); 2979 PrintF("Object elements have been normalized:\n");
2907 Print(); 2980 Print();
2908 } 2981 }
2909 #endif 2982 #endif
2910 2983
2911 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 2984 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
2912 return dictionary; 2985 return dictionary;
2913 } 2986 }
2914 2987
2915 2988
2989 MaybeObject* JSObject::GetHiddenProperties(HiddenPropertiesFlag flag) {
2990 Isolate* isolate = GetIsolate();
2991 Heap* heap = isolate->heap();
2992 Object* holder = BypassGlobalProxy();
2993 if (holder->IsUndefined()) return heap->undefined_value();
2994 JSObject* obj = JSObject::cast(holder);
2995 if (obj->HasFastProperties()) {
2996 // If the object has fast properties, check whether the first slot
2997 // in the descriptor array matches the hidden symbol. Since the
2998 // hidden symbols hash code is zero (and no other string has hash
2999 // code zero) it will always occupy the first entry if present.
3000 DescriptorArray* descriptors = obj->map()->instance_descriptors();
3001 if ((descriptors->number_of_descriptors() > 0) &&
3002 (descriptors->GetKey(0) == heap->hidden_symbol()) &&
3003 descriptors->IsProperty(0)) {
3004 ASSERT(descriptors->GetType(0) == FIELD);
3005 return obj->FastPropertyAt(descriptors->GetFieldIndex(0));
3006 }
3007 }
3008
3009 // Only attempt to find the hidden properties in the local object and not
3010 // in the prototype chain.
3011 if (!obj->HasHiddenPropertiesObject()) {
3012 // Hidden properties object not found. Allocate a new hidden properties
3013 // object if requested. Otherwise return the undefined value.
3014 if (flag == ALLOW_CREATION) {
3015 Object* hidden_obj;
3016 { MaybeObject* maybe_obj = heap->AllocateJSObject(
3017 isolate->context()->global_context()->object_function());
3018 if (!maybe_obj->ToObject(&hidden_obj)) return maybe_obj;
3019 }
3020 return obj->SetHiddenPropertiesObject(hidden_obj);
3021 } else {
3022 return heap->undefined_value();
3023 }
3024 }
3025 return obj->GetHiddenPropertiesObject();
3026 }
3027
3028
3029 MaybeObject* JSObject::GetIdentityHash(HiddenPropertiesFlag flag) {
3030 Isolate* isolate = GetIsolate();
3031 Object* hidden_props_obj;
3032 { MaybeObject* maybe_obj = GetHiddenProperties(flag);
3033 if (!maybe_obj->ToObject(&hidden_props_obj)) return maybe_obj;
3034 }
3035 if (!hidden_props_obj->IsJSObject()) {
3036 // We failed to create hidden properties. That's a detached
3037 // global proxy.
3038 ASSERT(hidden_props_obj->IsUndefined());
3039 return Smi::FromInt(0);
3040 }
3041 JSObject* hidden_props = JSObject::cast(hidden_props_obj);
3042 String* hash_symbol = isolate->heap()->identity_hash_symbol();
3043 {
3044 // Note that HasLocalProperty() can cause a GC in the general case in the
3045 // presence of interceptors.
3046 AssertNoAllocation no_alloc;
3047 if (hidden_props->HasLocalProperty(hash_symbol)) {
3048 MaybeObject* hash = hidden_props->GetProperty(hash_symbol);
3049 return Smi::cast(hash->ToObjectChecked());
3050 }
3051 }
3052
3053 int hash_value;
3054 int attempts = 0;
3055 do {
3056 // Generate a random 32-bit hash value but limit range to fit
3057 // within a smi.
3058 hash_value = V8::Random(isolate) & Smi::kMaxValue;
3059 attempts++;
3060 } while (hash_value == 0 && attempts < 30);
3061 hash_value = hash_value != 0 ? hash_value : 1; // never return 0
3062
3063 Smi* hash = Smi::FromInt(hash_value);
3064 { MaybeObject* result = hidden_props->SetLocalPropertyIgnoreAttributes(
3065 hash_symbol,
3066 hash,
3067 static_cast<PropertyAttributes>(None));
3068 if (result->IsFailure()) return result;
3069 }
3070 return hash;
3071 }
3072
3073
2916 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, 3074 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
2917 DeleteMode mode) { 3075 DeleteMode mode) {
2918 // Check local property, ignore interceptor. 3076 // Check local property, ignore interceptor.
2919 LookupResult result; 3077 LookupResult result;
2920 LocalLookupRealNamedProperty(name, &result); 3078 LocalLookupRealNamedProperty(name, &result);
2921 if (!result.IsProperty()) return GetHeap()->true_value(); 3079 if (!result.IsProperty()) return GetHeap()->true_value();
2922 3080
2923 // Normalize object if needed. 3081 // Normalize object if needed.
2924 Object* obj; 3082 Object* obj;
2925 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 3083 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
3151 switch (GetElementsKind()) { 3309 switch (GetElementsKind()) {
3152 case FAST_ELEMENTS: 3310 case FAST_ELEMENTS:
3153 return DeleteFastElement(index); 3311 return DeleteFastElement(index);
3154 3312
3155 case DICTIONARY_ELEMENTS: 3313 case DICTIONARY_ELEMENTS:
3156 return DeleteDictionaryElement(index, mode); 3314 return DeleteDictionaryElement(index, mode);
3157 3315
3158 case FAST_DOUBLE_ELEMENTS: { 3316 case FAST_DOUBLE_ELEMENTS: {
3159 int length = IsJSArray() 3317 int length = IsJSArray()
3160 ? Smi::cast(JSArray::cast(this)->length())->value() 3318 ? Smi::cast(JSArray::cast(this)->length())->value()
3161 : FixedArray::cast(elements())->length(); 3319 : FixedDoubleArray::cast(elements())->length();
3162 if (index < static_cast<uint32_t>(length)) { 3320 if (index < static_cast<uint32_t>(length)) {
3163 FixedDoubleArray::cast(elements())->set_the_hole(index); 3321 FixedDoubleArray::cast(elements())->set_the_hole(index);
3164 } 3322 }
3165 break; 3323 break;
3166 } 3324 }
3167 case EXTERNAL_PIXEL_ELEMENTS: 3325 case EXTERNAL_PIXEL_ELEMENTS:
3168 case EXTERNAL_BYTE_ELEMENTS: 3326 case EXTERNAL_BYTE_ELEMENTS:
3169 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3327 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3170 case EXTERNAL_SHORT_ELEMENTS: 3328 case EXTERNAL_SHORT_ELEMENTS:
3171 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3329 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
(...skipping 23 matching lines...) Expand all
3195 return DeleteFastElement(index); 3353 return DeleteFastElement(index);
3196 } 3354 }
3197 } 3355 }
3198 break; 3356 break;
3199 } 3357 }
3200 } 3358 }
3201 return isolate->heap()->true_value(); 3359 return isolate->heap()->true_value();
3202 } 3360 }
3203 3361
3204 3362
3363 MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) {
3364 if (IsJSProxy()) {
3365 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode);
3366 } else {
3367 return JSObject::cast(this)->DeleteProperty(name, mode);
3368 }
3369 }
3370
3371
3205 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { 3372 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
3206 Isolate* isolate = GetIsolate(); 3373 Isolate* isolate = GetIsolate();
3207 // ECMA-262, 3rd, 8.6.2.5 3374 // ECMA-262, 3rd, 8.6.2.5
3208 ASSERT(name->IsString()); 3375 ASSERT(name->IsString());
3209 3376
3210 // Check access rights if needed. 3377 // Check access rights if needed.
3211 if (IsAccessCheckNeeded() && 3378 if (IsAccessCheckNeeded() &&
3212 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { 3379 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) {
3213 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); 3380 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
3214 return isolate->heap()->false_value(); 3381 return isolate->heap()->false_value();
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
3592 if (!CanSetCallback(name)) { 3759 if (!CanSetCallback(name)) {
3593 return heap->undefined_value(); 3760 return heap->undefined_value();
3594 } 3761 }
3595 3762
3596 uint32_t index = 0; 3763 uint32_t index = 0;
3597 bool is_element = name->AsArrayIndex(&index); 3764 bool is_element = name->AsArrayIndex(&index);
3598 3765
3599 if (is_element) { 3766 if (is_element) {
3600 switch (GetElementsKind()) { 3767 switch (GetElementsKind()) {
3601 case FAST_ELEMENTS: 3768 case FAST_ELEMENTS:
3769 case FAST_DOUBLE_ELEMENTS:
3602 break; 3770 break;
3603 case EXTERNAL_PIXEL_ELEMENTS: 3771 case EXTERNAL_PIXEL_ELEMENTS:
3604 case EXTERNAL_BYTE_ELEMENTS: 3772 case EXTERNAL_BYTE_ELEMENTS:
3605 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3773 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3606 case EXTERNAL_SHORT_ELEMENTS: 3774 case EXTERNAL_SHORT_ELEMENTS:
3607 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3775 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3608 case EXTERNAL_INT_ELEMENTS: 3776 case EXTERNAL_INT_ELEMENTS:
3609 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3777 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3610 case EXTERNAL_FLOAT_ELEMENTS: 3778 case EXTERNAL_FLOAT_ELEMENTS:
3611 case EXTERNAL_DOUBLE_ELEMENTS: 3779 case EXTERNAL_DOUBLE_ELEMENTS:
3612 case FAST_DOUBLE_ELEMENTS:
3613 // Ignore getters and setters on pixel and external array 3780 // Ignore getters and setters on pixel and external array
3614 // elements. 3781 // elements.
3615 return heap->undefined_value(); 3782 return heap->undefined_value();
3616 case DICTIONARY_ELEMENTS: { 3783 case DICTIONARY_ELEMENTS: {
3617 Object* probe = 3784 Object* probe =
3618 FindGetterSetterInDictionary(element_dictionary(), index, heap); 3785 FindGetterSetterInDictionary(element_dictionary(), index, heap);
3619 if (!probe->IsTheHole()) return probe; 3786 if (!probe->IsTheHole()) return probe;
3620 // Otherwise allow to override it. 3787 // Otherwise allow to override it.
3621 break; 3788 break;
3622 } 3789 }
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
3841 4008
3842 uint32_t index = 0; 4009 uint32_t index = 0;
3843 bool is_element = name->AsArrayIndex(&index); 4010 bool is_element = name->AsArrayIndex(&index);
3844 4011
3845 if (is_element) { 4012 if (is_element) {
3846 if (IsJSArray()) return isolate->heap()->undefined_value(); 4013 if (IsJSArray()) return isolate->heap()->undefined_value();
3847 4014
3848 // Accessors overwrite previous callbacks (cf. with getters/setters). 4015 // Accessors overwrite previous callbacks (cf. with getters/setters).
3849 switch (GetElementsKind()) { 4016 switch (GetElementsKind()) {
3850 case FAST_ELEMENTS: 4017 case FAST_ELEMENTS:
4018 case FAST_DOUBLE_ELEMENTS:
3851 break; 4019 break;
3852 case EXTERNAL_PIXEL_ELEMENTS: 4020 case EXTERNAL_PIXEL_ELEMENTS:
3853 case EXTERNAL_BYTE_ELEMENTS: 4021 case EXTERNAL_BYTE_ELEMENTS:
3854 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4022 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3855 case EXTERNAL_SHORT_ELEMENTS: 4023 case EXTERNAL_SHORT_ELEMENTS:
3856 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4024 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3857 case EXTERNAL_INT_ELEMENTS: 4025 case EXTERNAL_INT_ELEMENTS:
3858 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4026 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3859 case EXTERNAL_FLOAT_ELEMENTS: 4027 case EXTERNAL_FLOAT_ELEMENTS:
3860 case EXTERNAL_DOUBLE_ELEMENTS: 4028 case EXTERNAL_DOUBLE_ELEMENTS:
3861 case FAST_DOUBLE_ELEMENTS:
3862 // Ignore getters and setters on pixel and external array 4029 // Ignore getters and setters on pixel and external array
3863 // elements. 4030 // elements.
3864 return isolate->heap()->undefined_value(); 4031 return isolate->heap()->undefined_value();
3865 case DICTIONARY_ELEMENTS: 4032 case DICTIONARY_ELEMENTS:
3866 break; 4033 break;
3867 case NON_STRICT_ARGUMENTS_ELEMENTS: 4034 case NON_STRICT_ARGUMENTS_ELEMENTS:
3868 UNIMPLEMENTED(); 4035 UNIMPLEMENTED();
3869 break; 4036 break;
3870 } 4037 }
3871 4038
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
4624 cache->ElementAdded(); 4791 cache->ElementAdded();
4625 return cache; 4792 return cache;
4626 } 4793 }
4627 4794
4628 4795
4629 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { 4796 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) {
4630 ASSERT(!array->HasExternalArrayElements()); 4797 ASSERT(!array->HasExternalArrayElements());
4631 switch (array->GetElementsKind()) { 4798 switch (array->GetElementsKind()) {
4632 case JSObject::FAST_ELEMENTS: 4799 case JSObject::FAST_ELEMENTS:
4633 return UnionOfKeys(FixedArray::cast(array->elements())); 4800 return UnionOfKeys(FixedArray::cast(array->elements()));
4801 case JSObject::FAST_DOUBLE_ELEMENTS:
4802 return UnionOfDoubleKeys(FixedDoubleArray::cast(array->elements()));
4803 break;
4634 case JSObject::DICTIONARY_ELEMENTS: { 4804 case JSObject::DICTIONARY_ELEMENTS: {
4635 NumberDictionary* dict = array->element_dictionary(); 4805 NumberDictionary* dict = array->element_dictionary();
4636 int size = dict->NumberOfElements(); 4806 int size = dict->NumberOfElements();
4637 4807
4638 // Allocate a temporary fixed array. 4808 // Allocate a temporary fixed array.
4639 Object* object; 4809 Object* object;
4640 { MaybeObject* maybe_object = GetHeap()->AllocateFixedArray(size); 4810 { MaybeObject* maybe_object = GetHeap()->AllocateFixedArray(size);
4641 if (!maybe_object->ToObject(&object)) return maybe_object; 4811 if (!maybe_object->ToObject(&object)) return maybe_object;
4642 } 4812 }
4643 FixedArray* key_array = FixedArray::cast(object); 4813 FixedArray* key_array = FixedArray::cast(object);
(...skipping 14 matching lines...) Expand all
4658 break; 4828 break;
4659 case JSObject::EXTERNAL_BYTE_ELEMENTS: 4829 case JSObject::EXTERNAL_BYTE_ELEMENTS:
4660 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4830 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4661 case JSObject::EXTERNAL_SHORT_ELEMENTS: 4831 case JSObject::EXTERNAL_SHORT_ELEMENTS:
4662 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4832 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
4663 case JSObject::EXTERNAL_INT_ELEMENTS: 4833 case JSObject::EXTERNAL_INT_ELEMENTS:
4664 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: 4834 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
4665 case JSObject::EXTERNAL_FLOAT_ELEMENTS: 4835 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
4666 case JSObject::EXTERNAL_DOUBLE_ELEMENTS: 4836 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
4667 case JSObject::EXTERNAL_PIXEL_ELEMENTS: 4837 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
4668 case JSObject::FAST_DOUBLE_ELEMENTS:
4669 break; 4838 break;
4670 } 4839 }
4671 UNREACHABLE(); 4840 UNREACHABLE();
4672 return GetHeap()->null_value(); // Failure case needs to "return" a value. 4841 return GetHeap()->null_value(); // Failure case needs to "return" a value.
4673 } 4842 }
4674 4843
4675 4844
4676 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { 4845 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) {
4677 int len0 = length(); 4846 int len0 = length();
4678 #ifdef DEBUG 4847 #ifdef DEBUG
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4720 ASSERT(e->IsString() || e->IsNumber()); 4889 ASSERT(e->IsString() || e->IsNumber());
4721 result->set(len0 + index, e, mode); 4890 result->set(len0 + index, e, mode);
4722 index++; 4891 index++;
4723 } 4892 }
4724 } 4893 }
4725 ASSERT(extra == index); 4894 ASSERT(extra == index);
4726 return result; 4895 return result;
4727 } 4896 }
4728 4897
4729 4898
4899 MaybeObject* FixedArray::UnionOfDoubleKeys(FixedDoubleArray* other) {
4900 int len0 = length();
4901 #ifdef DEBUG
4902 if (FLAG_enable_slow_asserts) {
4903 for (int i = 0; i < len0; i++) {
4904 ASSERT(get(i)->IsString() || get(i)->IsNumber());
4905 }
4906 }
4907 #endif
4908 int len1 = other->length();
4909 // Optimize if 'other' is empty.
4910 // We cannot optimize if 'this' is empty, as other may have holes
4911 // or non keys.
4912 if (len1 == 0) return this;
4913
4914 // Compute how many elements are not in this.
4915 int extra = 0;
4916 Heap* heap = GetHeap();
4917 Object* obj;
4918 for (int y = 0; y < len1; y++) {
4919 if (!other->is_the_hole(y)) {
4920 MaybeObject* maybe_obj = heap->NumberFromDouble(other->get(y));
4921 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
4922 if (!HasKey(this, obj)) extra++;
4923 }
4924 }
4925
4926 if (extra == 0) return this;
4927
4928 // Allocate the result
4929 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(len0 + extra);
4930 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
4931 }
4932 // Fill in the content
4933 FixedArray* result = FixedArray::cast(obj);
4934 {
4935 // Limit the scope of the AssertNoAllocation
4936 AssertNoAllocation no_gc;
4937 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
4938 for (int i = 0; i < len0; i++) {
4939 Object* e = get(i);
4940 ASSERT(e->IsString() || e->IsNumber());
4941 result->set(i, e, mode);
4942 }
4943 }
4944
4945 // Fill in the extra keys.
4946 int index = 0;
4947 for (int y = 0; y < len1; y++) {
4948 if (!other->is_the_hole(y)) {
4949 MaybeObject* maybe_obj = heap->NumberFromDouble(other->get(y));
4950 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
4951 if (!HasKey(this, obj)) {
4952 result->set(len0 + index, obj);
4953 index++;
4954 }
4955 }
4956 }
4957 ASSERT(extra == index);
4958 return result;
4959 }
4960
4961
4730 MaybeObject* FixedArray::CopySize(int new_length) { 4962 MaybeObject* FixedArray::CopySize(int new_length) {
4731 Heap* heap = GetHeap(); 4963 Heap* heap = GetHeap();
4732 if (new_length == 0) return heap->empty_fixed_array(); 4964 if (new_length == 0) return heap->empty_fixed_array();
4733 Object* obj; 4965 Object* obj;
4734 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length); 4966 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length);
4735 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 4967 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
4736 } 4968 }
4737 FixedArray* result = FixedArray::cast(obj); 4969 FixedArray* result = FixedArray::cast(obj);
4738 // Copy the content 4970 // Copy the content
4739 AssertNoAllocation no_gc; 4971 AssertNoAllocation no_gc;
(...skipping 2405 matching lines...) Expand 10 before | Expand all | Expand 10 after
7145 case BUILTIN: return "BUILTIN"; 7377 case BUILTIN: return "BUILTIN";
7146 case LOAD_IC: return "LOAD_IC"; 7378 case LOAD_IC: return "LOAD_IC";
7147 case KEYED_LOAD_IC: return "KEYED_LOAD_IC"; 7379 case KEYED_LOAD_IC: return "KEYED_LOAD_IC";
7148 case STORE_IC: return "STORE_IC"; 7380 case STORE_IC: return "STORE_IC";
7149 case KEYED_STORE_IC: return "KEYED_STORE_IC"; 7381 case KEYED_STORE_IC: return "KEYED_STORE_IC";
7150 case CALL_IC: return "CALL_IC"; 7382 case CALL_IC: return "CALL_IC";
7151 case KEYED_CALL_IC: return "KEYED_CALL_IC"; 7383 case KEYED_CALL_IC: return "KEYED_CALL_IC";
7152 case UNARY_OP_IC: return "UNARY_OP_IC"; 7384 case UNARY_OP_IC: return "UNARY_OP_IC";
7153 case BINARY_OP_IC: return "BINARY_OP_IC"; 7385 case BINARY_OP_IC: return "BINARY_OP_IC";
7154 case COMPARE_IC: return "COMPARE_IC"; 7386 case COMPARE_IC: return "COMPARE_IC";
7387 case TO_BOOLEAN_IC: return "TO_BOOLEAN_IC";
7155 } 7388 }
7156 UNREACHABLE(); 7389 UNREACHABLE();
7157 return NULL; 7390 return NULL;
7158 } 7391 }
7159 7392
7160 7393
7161 const char* Code::ICState2String(InlineCacheState state) { 7394 const char* Code::ICState2String(InlineCacheState state) {
7162 switch (state) { 7395 switch (state) {
7163 case UNINITIALIZED: return "UNINITIALIZED"; 7396 case UNINITIALIZED: return "UNINITIALIZED";
7164 case PREMONOMORPHIC: return "PREMONOMORPHIC"; 7397 case PREMONOMORPHIC: return "PREMONOMORPHIC";
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
7335 7568
7336 // Find the new map to use for this object if there is a map change. 7569 // Find the new map to use for this object if there is a map change.
7337 Map* new_map = NULL; 7570 Map* new_map = NULL;
7338 if (elements()->map() != heap->non_strict_arguments_elements_map()) { 7571 if (elements()->map() != heap->non_strict_arguments_elements_map()) {
7339 Object* object; 7572 Object* object;
7340 MaybeObject* maybe = map()->GetFastElementsMap(); 7573 MaybeObject* maybe = map()->GetFastElementsMap();
7341 if (!maybe->ToObject(&object)) return maybe; 7574 if (!maybe->ToObject(&object)) return maybe;
7342 new_map = Map::cast(object); 7575 new_map = Map::cast(object);
7343 } 7576 }
7344 7577
7345 AssertNoAllocation no_gc;
7346 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7347 switch (GetElementsKind()) { 7578 switch (GetElementsKind()) {
7348 case FAST_ELEMENTS: 7579 case FAST_ELEMENTS: {
7580 AssertNoAllocation no_gc;
7581 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7349 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode); 7582 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode);
7350 set_map(new_map); 7583 set_map(new_map);
7351 set_elements(new_elements); 7584 set_elements(new_elements);
7352 break; 7585 break;
7353 case DICTIONARY_ELEMENTS: 7586 }
7587 case DICTIONARY_ELEMENTS: {
7588 AssertNoAllocation no_gc;
7589 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7354 CopySlowElementsToFast(NumberDictionary::cast(elements()), 7590 CopySlowElementsToFast(NumberDictionary::cast(elements()),
7355 new_elements, 7591 new_elements,
7356 mode); 7592 mode);
7357 set_map(new_map); 7593 set_map(new_map);
7358 set_elements(new_elements); 7594 set_elements(new_elements);
7359 break; 7595 break;
7596 }
7360 case NON_STRICT_ARGUMENTS_ELEMENTS: { 7597 case NON_STRICT_ARGUMENTS_ELEMENTS: {
7598 AssertNoAllocation no_gc;
7599 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7361 // The object's map and the parameter map are unchanged, the unaliased 7600 // The object's map and the parameter map are unchanged, the unaliased
7362 // arguments are copied to the new backing store. 7601 // arguments are copied to the new backing store.
7363 FixedArray* parameter_map = FixedArray::cast(elements()); 7602 FixedArray* parameter_map = FixedArray::cast(elements());
7364 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 7603 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
7365 if (arguments->IsDictionary()) { 7604 if (arguments->IsDictionary()) {
7366 CopySlowElementsToFast(NumberDictionary::cast(arguments), 7605 CopySlowElementsToFast(NumberDictionary::cast(arguments),
7367 new_elements, 7606 new_elements,
7368 mode); 7607 mode);
7369 } else { 7608 } else {
7370 CopyFastElementsToFast(arguments, new_elements, mode); 7609 CopyFastElementsToFast(arguments, new_elements, mode);
(...skipping 15 matching lines...) Expand all
7386 MaybeObject* maybe_value_object = 7625 MaybeObject* maybe_value_object =
7387 GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED); 7626 GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED);
7388 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object; 7627 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object;
7389 // Force write barrier. It's not worth trying to exploit 7628 // Force write barrier. It's not worth trying to exploit
7390 // elems->GetWriteBarrierMode(), since it requires an 7629 // elems->GetWriteBarrierMode(), since it requires an
7391 // AssertNoAllocation stack object that would have to be positioned 7630 // AssertNoAllocation stack object that would have to be positioned
7392 // after the HeapNumber allocation anyway. 7631 // after the HeapNumber allocation anyway.
7393 new_elements->set(i, obj, UPDATE_WRITE_BARRIER); 7632 new_elements->set(i, obj, UPDATE_WRITE_BARRIER);
7394 } 7633 }
7395 } 7634 }
7635 set_map(new_map);
7636 set_elements(new_elements);
7396 break; 7637 break;
7397 } 7638 }
7398 case EXTERNAL_BYTE_ELEMENTS: 7639 case EXTERNAL_BYTE_ELEMENTS:
7399 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 7640 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
7400 case EXTERNAL_SHORT_ELEMENTS: 7641 case EXTERNAL_SHORT_ELEMENTS:
7401 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 7642 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7402 case EXTERNAL_INT_ELEMENTS: 7643 case EXTERNAL_INT_ELEMENTS:
7403 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 7644 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7404 case EXTERNAL_FLOAT_ELEMENTS: 7645 case EXTERNAL_FLOAT_ELEMENTS:
7405 case EXTERNAL_DOUBLE_ELEMENTS: 7646 case EXTERNAL_DOUBLE_ELEMENTS:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
7448 } 7689 }
7449 case DICTIONARY_ELEMENTS: { 7690 case DICTIONARY_ELEMENTS: {
7450 elems->Initialize(NumberDictionary::cast(elements())); 7691 elems->Initialize(NumberDictionary::cast(elements()));
7451 break; 7692 break;
7452 } 7693 }
7453 default: 7694 default:
7454 UNREACHABLE(); 7695 UNREACHABLE();
7455 break; 7696 break;
7456 } 7697 }
7457 7698
7699 ASSERT(new_map->has_fast_double_elements());
7458 set_map(new_map); 7700 set_map(new_map);
7701 ASSERT(elems->IsFixedDoubleArray());
7459 set_elements(elems); 7702 set_elements(elems);
7460 7703
7461 if (IsJSArray()) { 7704 if (IsJSArray()) {
7462 JSArray::cast(this)->set_length(Smi::FromInt(length)); 7705 JSArray::cast(this)->set_length(Smi::FromInt(length));
7463 } 7706 }
7464 7707
7465 return this; 7708 return this;
7466 } 7709 }
7467 7710
7468 7711
7469 MaybeObject* JSObject::SetSlowElements(Object* len) { 7712 MaybeObject* JSObject::SetSlowElements(Object* len) {
7470 // We should never end in here with a pixel or external array. 7713 // We should never end in here with a pixel or external array.
7471 ASSERT(!HasExternalArrayElements()); 7714 ASSERT(!HasExternalArrayElements());
7472 7715
7473 uint32_t new_length = static_cast<uint32_t>(len->Number()); 7716 uint32_t new_length = static_cast<uint32_t>(len->Number());
7474 7717
7475 switch (GetElementsKind()) { 7718 switch (GetElementsKind()) {
7476 case FAST_ELEMENTS: { 7719 case FAST_ELEMENTS: {
7720 case FAST_DOUBLE_ELEMENTS:
7477 // Make sure we never try to shrink dense arrays into sparse arrays. 7721 // Make sure we never try to shrink dense arrays into sparse arrays.
7478 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= 7722 ASSERT(static_cast<uint32_t>(
7479 new_length); 7723 FixedArrayBase::cast(elements())->length()) <= new_length);
7480 MaybeObject* result = NormalizeElements(); 7724 MaybeObject* result = NormalizeElements();
7481 if (result->IsFailure()) return result; 7725 if (result->IsFailure()) return result;
7482 7726
7483 // Update length for JSArrays. 7727 // Update length for JSArrays.
7484 if (IsJSArray()) JSArray::cast(this)->set_length(len); 7728 if (IsJSArray()) JSArray::cast(this)->set_length(len);
7485 break; 7729 break;
7486 } 7730 }
7487 case DICTIONARY_ELEMENTS: { 7731 case DICTIONARY_ELEMENTS: {
7488 if (IsJSArray()) { 7732 if (IsJSArray()) {
7489 uint32_t old_length = 7733 uint32_t old_length =
7490 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); 7734 static_cast<uint32_t>(JSArray::cast(this)->length()->Number());
7491 element_dictionary()->RemoveNumberEntries(new_length, old_length), 7735 element_dictionary()->RemoveNumberEntries(new_length, old_length),
7492 JSArray::cast(this)->set_length(len); 7736 JSArray::cast(this)->set_length(len);
7493 } 7737 }
7494 break; 7738 break;
7495 } 7739 }
7496 case NON_STRICT_ARGUMENTS_ELEMENTS: 7740 case NON_STRICT_ARGUMENTS_ELEMENTS:
7497 UNIMPLEMENTED(); 7741 UNIMPLEMENTED();
7498 break; 7742 break;
7499 case EXTERNAL_BYTE_ELEMENTS: 7743 case EXTERNAL_BYTE_ELEMENTS:
7500 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 7744 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
7501 case EXTERNAL_SHORT_ELEMENTS: 7745 case EXTERNAL_SHORT_ELEMENTS:
7502 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 7746 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7503 case EXTERNAL_INT_ELEMENTS: 7747 case EXTERNAL_INT_ELEMENTS:
7504 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 7748 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7505 case EXTERNAL_FLOAT_ELEMENTS: 7749 case EXTERNAL_FLOAT_ELEMENTS:
7506 case EXTERNAL_DOUBLE_ELEMENTS: 7750 case EXTERNAL_DOUBLE_ELEMENTS:
7507 case EXTERNAL_PIXEL_ELEMENTS: 7751 case EXTERNAL_PIXEL_ELEMENTS:
7508 case FAST_DOUBLE_ELEMENTS:
7509 UNREACHABLE(); 7752 UNREACHABLE();
7510 break; 7753 break;
7511 } 7754 }
7512 return this; 7755 return this;
7513 } 7756 }
7514 7757
7515 7758
7516 MaybeObject* JSArray::Initialize(int capacity) { 7759 MaybeObject* JSArray::Initialize(int capacity) {
7517 Heap* heap = GetHeap(); 7760 Heap* heap = GetHeap();
7518 ASSERT(capacity >= 0); 7761 ASSERT(capacity >= 0);
(...skipping 19 matching lines...) Expand all
7538 int old_size = old_backing->length(); 7781 int old_size = old_backing->length();
7539 int new_size = required_size > old_size ? required_size : old_size; 7782 int new_size = required_size > old_size ? required_size : old_size;
7540 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size); 7783 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size);
7541 // Can't use this any more now because we may have had a GC! 7784 // Can't use this any more now because we may have had a GC!
7542 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); 7785 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i));
7543 self->SetContent(*new_backing); 7786 self->SetContent(*new_backing);
7544 } 7787 }
7545 7788
7546 7789
7547 static Failure* ArrayLengthRangeError(Heap* heap) { 7790 static Failure* ArrayLengthRangeError(Heap* heap) {
7548 HandleScope scope; 7791 HandleScope scope(heap->isolate());
7549 return heap->isolate()->Throw( 7792 return heap->isolate()->Throw(
7550 *FACTORY->NewRangeError("invalid_array_length", 7793 *FACTORY->NewRangeError("invalid_array_length",
7551 HandleVector<Object>(NULL, 0))); 7794 HandleVector<Object>(NULL, 0)));
7552 } 7795 }
7553 7796
7554 7797
7555 MaybeObject* JSObject::SetElementsLength(Object* len) { 7798 MaybeObject* JSObject::SetElementsLength(Object* len) {
7556 // We should never end in here with a pixel or external array. 7799 // We should never end in here with a pixel or external array.
7557 ASSERT(AllowsSetElementsLength()); 7800 ASSERT(AllowsSetElementsLength());
7558 7801
7559 MaybeObject* maybe_smi_length = len->ToSmi(); 7802 MaybeObject* maybe_smi_length = len->ToSmi();
7560 Object* smi_length = Smi::FromInt(0); 7803 Object* smi_length = Smi::FromInt(0);
7561 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { 7804 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
7562 const int value = Smi::cast(smi_length)->value(); 7805 const int value = Smi::cast(smi_length)->value();
7563 if (value < 0) return ArrayLengthRangeError(GetHeap()); 7806 if (value < 0) return ArrayLengthRangeError(GetHeap());
7564 switch (GetElementsKind()) { 7807 JSObject::ElementsKind elements_kind = GetElementsKind();
7565 case FAST_ELEMENTS: { 7808 switch (elements_kind) {
7566 int old_capacity = FixedArray::cast(elements())->length(); 7809 case FAST_ELEMENTS:
7810 case FAST_DOUBLE_ELEMENTS: {
7811 int old_capacity = FixedArrayBase::cast(elements())->length();
7567 if (value <= old_capacity) { 7812 if (value <= old_capacity) {
7568 if (IsJSArray()) { 7813 if (IsJSArray()) {
7569 Object* obj; 7814 Object* obj;
7570 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 7815 if (elements_kind == FAST_ELEMENTS) {
7816 MaybeObject* maybe_obj = EnsureWritableFastElements();
7571 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7817 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7572 } 7818 }
7573 FixedArray* fast_elements = FixedArray::cast(elements());
7574 if (2 * value <= old_capacity) { 7819 if (2 * value <= old_capacity) {
7575 // If more than half the elements won't be used, trim the array. 7820 // If more than half the elements won't be used, trim the array.
7576 if (value == 0) { 7821 if (value == 0) {
7577 initialize_elements(); 7822 initialize_elements();
7578 } else { 7823 } else {
7579 fast_elements->set_length(value); 7824 Address filler_start;
7580 Address filler_start = fast_elements->address() + 7825 int filler_size;
7581 FixedArray::OffsetOfElementAt(value); 7826 if (GetElementsKind() == FAST_ELEMENTS) {
7582 int filler_size = (old_capacity - value) * kPointerSize; 7827 FixedArray* fast_elements = FixedArray::cast(elements());
7828 fast_elements->set_length(value);
7829 filler_start = fast_elements->address() +
7830 FixedArray::OffsetOfElementAt(value);
7831 filler_size = (old_capacity - value) * kPointerSize;
7832 } else {
7833 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
7834 FixedDoubleArray* fast_double_elements =
7835 FixedDoubleArray::cast(elements());
7836 fast_double_elements->set_length(value);
7837 filler_start = fast_double_elements->address() +
7838 FixedDoubleArray::OffsetOfElementAt(value);
7839 filler_size = (old_capacity - value) * kDoubleSize;
7840 }
7583 GetHeap()->CreateFillerObjectAt(filler_start, filler_size); 7841 GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
7584 } 7842 }
7585 } else { 7843 } else {
7586 // Otherwise, fill the unused tail with holes. 7844 // Otherwise, fill the unused tail with holes.
7587 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); 7845 int old_length = FastD2I(JSArray::cast(this)->length()->Number());
7588 for (int i = value; i < old_length; i++) { 7846 if (GetElementsKind() == FAST_ELEMENTS) {
7589 fast_elements->set_the_hole(i); 7847 FixedArray* fast_elements = FixedArray::cast(elements());
7848 for (int i = value; i < old_length; i++) {
7849 fast_elements->set_the_hole(i);
7850 }
7851 } else {
7852 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
7853 FixedDoubleArray* fast_double_elements =
7854 FixedDoubleArray::cast(elements());
7855 for (int i = value; i < old_length; i++) {
7856 fast_double_elements->set_the_hole(i);
7857 }
7590 } 7858 }
7591 } 7859 }
7592 JSArray::cast(this)->set_length(Smi::cast(smi_length)); 7860 JSArray::cast(this)->set_length(Smi::cast(smi_length));
7593 } 7861 }
7594 return this; 7862 return this;
7595 } 7863 }
7596 int min = NewElementsCapacity(old_capacity); 7864 int min = NewElementsCapacity(old_capacity);
7597 int new_capacity = value > min ? value : min; 7865 int new_capacity = value > min ? value : min;
7598 if (new_capacity <= kMaxFastElementsLength || 7866 if (!ShouldConvertToSlowElements(new_capacity)) {
7599 !ShouldConvertToSlowElements(new_capacity)) { 7867 MaybeObject* result;
7600 MaybeObject* result = 7868 if (GetElementsKind() == FAST_ELEMENTS) {
7601 SetFastElementsCapacityAndLength(new_capacity, value); 7869 result = SetFastElementsCapacityAndLength(new_capacity, value);
7870 } else {
7871 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
7872 result = SetFastDoubleElementsCapacityAndLength(new_capacity,
7873 value);
7874 }
7602 if (result->IsFailure()) return result; 7875 if (result->IsFailure()) return result;
7603 return this; 7876 return this;
7604 } 7877 }
7605 break; 7878 break;
7606 } 7879 }
7607 case DICTIONARY_ELEMENTS: { 7880 case DICTIONARY_ELEMENTS: {
7608 if (IsJSArray()) { 7881 if (IsJSArray()) {
7609 if (value == 0) { 7882 if (value == 0) {
7610 // If the length of a slow array is reset to zero, we clear 7883 // If the length of a slow array is reset to zero, we clear
7611 // the array and flush backing storage. This has the added 7884 // the array and flush backing storage. This has the added
(...skipping 15 matching lines...) Expand all
7627 case NON_STRICT_ARGUMENTS_ELEMENTS: 7900 case NON_STRICT_ARGUMENTS_ELEMENTS:
7628 case EXTERNAL_BYTE_ELEMENTS: 7901 case EXTERNAL_BYTE_ELEMENTS:
7629 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 7902 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
7630 case EXTERNAL_SHORT_ELEMENTS: 7903 case EXTERNAL_SHORT_ELEMENTS:
7631 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 7904 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7632 case EXTERNAL_INT_ELEMENTS: 7905 case EXTERNAL_INT_ELEMENTS:
7633 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 7906 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7634 case EXTERNAL_FLOAT_ELEMENTS: 7907 case EXTERNAL_FLOAT_ELEMENTS:
7635 case EXTERNAL_DOUBLE_ELEMENTS: 7908 case EXTERNAL_DOUBLE_ELEMENTS:
7636 case EXTERNAL_PIXEL_ELEMENTS: 7909 case EXTERNAL_PIXEL_ELEMENTS:
7637 case FAST_DOUBLE_ELEMENTS:
7638 UNREACHABLE(); 7910 UNREACHABLE();
7639 break; 7911 break;
7640 } 7912 }
7641 } 7913 }
7642 7914
7643 // General slow case. 7915 // General slow case.
7644 if (len->IsNumber()) { 7916 if (len->IsNumber()) {
7645 uint32_t length; 7917 uint32_t length;
7646 if (len->ToArrayIndex(&length)) { 7918 if (len->ToArrayIndex(&length)) {
7647 return SetSlowElements(len); 7919 return SetSlowElements(len);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
7736 8008
7737 // From 8.6.2 Object Internal Methods 8009 // From 8.6.2 Object Internal Methods
7738 // ... 8010 // ...
7739 // In addition, if [[Extensible]] is false the value of the [[Class]] and 8011 // In addition, if [[Extensible]] is false the value of the [[Class]] and
7740 // [[Prototype]] internal properties of the object may not be modified. 8012 // [[Prototype]] internal properties of the object may not be modified.
7741 // ... 8013 // ...
7742 // Implementation specific extensions that modify [[Class]], [[Prototype]] 8014 // Implementation specific extensions that modify [[Class]], [[Prototype]]
7743 // or [[Extensible]] must not violate the invariants defined in the preceding 8015 // or [[Extensible]] must not violate the invariants defined in the preceding
7744 // paragraph. 8016 // paragraph.
7745 if (!this->map()->is_extensible()) { 8017 if (!this->map()->is_extensible()) {
7746 HandleScope scope; 8018 HandleScope scope(heap->isolate());
7747 Handle<Object> handle(this, heap->isolate()); 8019 Handle<Object> handle(this, heap->isolate());
7748 return heap->isolate()->Throw( 8020 return heap->isolate()->Throw(
7749 *FACTORY->NewTypeError("non_extensible_proto", 8021 *FACTORY->NewTypeError("non_extensible_proto",
7750 HandleVector<Object>(&handle, 1))); 8022 HandleVector<Object>(&handle, 1)));
7751 } 8023 }
7752 8024
7753 // Before we can set the prototype we need to be sure 8025 // Before we can set the prototype we need to be sure
7754 // prototype cycles are prevented. 8026 // prototype cycles are prevented.
7755 // It is sufficient to validate that the receiver is not in the new prototype 8027 // It is sufficient to validate that the receiver is not in the new prototype
7756 // chain. 8028 // chain.
7757 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) { 8029 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) {
7758 if (JSObject::cast(pt) == this) { 8030 if (JSObject::cast(pt) == this) {
7759 // Cycle detected. 8031 // Cycle detected.
7760 HandleScope scope; 8032 HandleScope scope(heap->isolate());
7761 return heap->isolate()->Throw( 8033 return heap->isolate()->Throw(
7762 *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0))); 8034 *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0)));
7763 } 8035 }
7764 } 8036 }
7765 8037
7766 JSReceiver* real_receiver = this; 8038 JSReceiver* real_receiver = this;
7767 8039
7768 if (skip_hidden_prototypes) { 8040 if (skip_hidden_prototypes) {
7769 // Find the first object in the chain whose prototype object is not 8041 // Find the first object in the chain whose prototype object is not
7770 // hidden and set the new prototype on that object. 8042 // hidden and set the new prototype on that object.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
7810 uint32_t length = IsJSArray() ? 8082 uint32_t length = IsJSArray() ?
7811 static_cast<uint32_t> 8083 static_cast<uint32_t>
7812 (Smi::cast(JSArray::cast(this)->length())->value()) : 8084 (Smi::cast(JSArray::cast(this)->length())->value()) :
7813 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 8085 static_cast<uint32_t>(FixedArray::cast(elements())->length());
7814 if ((index < length) && 8086 if ((index < length) &&
7815 !FixedArray::cast(elements())->get(index)->IsTheHole()) { 8087 !FixedArray::cast(elements())->get(index)->IsTheHole()) {
7816 return true; 8088 return true;
7817 } 8089 }
7818 break; 8090 break;
7819 } 8091 }
8092 case FAST_DOUBLE_ELEMENTS: {
8093 uint32_t length = IsJSArray() ?
8094 static_cast<uint32_t>
8095 (Smi::cast(JSArray::cast(this)->length())->value()) :
8096 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
8097 if ((index < length) &&
8098 !FixedDoubleArray::cast(elements())->is_the_hole(index)) {
8099 return true;
8100 }
8101 break;
8102 }
7820 case EXTERNAL_PIXEL_ELEMENTS: { 8103 case EXTERNAL_PIXEL_ELEMENTS: {
7821 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 8104 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
7822 if (index < static_cast<uint32_t>(pixels->length())) { 8105 if (index < static_cast<uint32_t>(pixels->length())) {
7823 return true; 8106 return true;
7824 } 8107 }
7825 break; 8108 break;
7826 } 8109 }
7827 case EXTERNAL_BYTE_ELEMENTS: 8110 case EXTERNAL_BYTE_ELEMENTS:
7828 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 8111 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
7829 case EXTERNAL_SHORT_ELEMENTS: 8112 case EXTERNAL_SHORT_ELEMENTS:
7830 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 8113 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7831 case EXTERNAL_INT_ELEMENTS: 8114 case EXTERNAL_INT_ELEMENTS:
7832 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 8115 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7833 case EXTERNAL_FLOAT_ELEMENTS: 8116 case EXTERNAL_FLOAT_ELEMENTS:
7834 case EXTERNAL_DOUBLE_ELEMENTS: 8117 case EXTERNAL_DOUBLE_ELEMENTS: {
7835 case FAST_DOUBLE_ELEMENTS: {
7836 ExternalArray* array = ExternalArray::cast(elements()); 8118 ExternalArray* array = ExternalArray::cast(elements());
7837 if (index < static_cast<uint32_t>(array->length())) { 8119 if (index < static_cast<uint32_t>(array->length())) {
7838 return true; 8120 return true;
7839 } 8121 }
7840 break; 8122 break;
7841 } 8123 }
7842 case DICTIONARY_ELEMENTS: { 8124 case DICTIONARY_ELEMENTS: {
7843 if (element_dictionary()->FindEntry(index) 8125 if (element_dictionary()->FindEntry(index)
7844 != NumberDictionary::kNotFound) { 8126 != NumberDictionary::kNotFound) {
7845 return true; 8127 return true;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
7936 uint32_t length = IsJSArray() ? 8218 uint32_t length = IsJSArray() ?
7937 static_cast<uint32_t> 8219 static_cast<uint32_t>
7938 (Smi::cast(JSArray::cast(this)->length())->value()) : 8220 (Smi::cast(JSArray::cast(this)->length())->value()) :
7939 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 8221 static_cast<uint32_t>(FixedArray::cast(elements())->length());
7940 if ((index < length) && 8222 if ((index < length) &&
7941 !FixedArray::cast(elements())->get(index)->IsTheHole()) { 8223 !FixedArray::cast(elements())->get(index)->IsTheHole()) {
7942 return FAST_ELEMENT; 8224 return FAST_ELEMENT;
7943 } 8225 }
7944 break; 8226 break;
7945 } 8227 }
8228 case FAST_DOUBLE_ELEMENTS: {
8229 uint32_t length = IsJSArray() ?
8230 static_cast<uint32_t>
8231 (Smi::cast(JSArray::cast(this)->length())->value()) :
8232 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
8233 if ((index < length) &&
8234 !FixedDoubleArray::cast(elements())->is_the_hole(index)) {
8235 return FAST_ELEMENT;
8236 }
8237 break;
8238 }
7946 case EXTERNAL_PIXEL_ELEMENTS: { 8239 case EXTERNAL_PIXEL_ELEMENTS: {
7947 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 8240 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
7948 if (index < static_cast<uint32_t>(pixels->length())) return FAST_ELEMENT; 8241 if (index < static_cast<uint32_t>(pixels->length())) return FAST_ELEMENT;
7949 break; 8242 break;
7950 } 8243 }
7951 case EXTERNAL_BYTE_ELEMENTS: 8244 case EXTERNAL_BYTE_ELEMENTS:
7952 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 8245 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
7953 case EXTERNAL_SHORT_ELEMENTS: 8246 case EXTERNAL_SHORT_ELEMENTS:
7954 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 8247 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7955 case EXTERNAL_INT_ELEMENTS: 8248 case EXTERNAL_INT_ELEMENTS:
7956 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 8249 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7957 case EXTERNAL_FLOAT_ELEMENTS: 8250 case EXTERNAL_FLOAT_ELEMENTS:
7958 case EXTERNAL_DOUBLE_ELEMENTS: { 8251 case EXTERNAL_DOUBLE_ELEMENTS: {
7959 ExternalArray* array = ExternalArray::cast(elements()); 8252 ExternalArray* array = ExternalArray::cast(elements());
7960 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; 8253 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT;
7961 break; 8254 break;
7962 } 8255 }
7963 case FAST_DOUBLE_ELEMENTS:
7964 UNREACHABLE();
7965 break;
7966 case DICTIONARY_ELEMENTS: { 8256 case DICTIONARY_ELEMENTS: {
7967 if (element_dictionary()->FindEntry(index) != 8257 if (element_dictionary()->FindEntry(index) !=
7968 NumberDictionary::kNotFound) { 8258 NumberDictionary::kNotFound) {
7969 return DICTIONARY_ELEMENT; 8259 return DICTIONARY_ELEMENT;
7970 } 8260 }
7971 break; 8261 break;
7972 } 8262 }
7973 case NON_STRICT_ARGUMENTS_ELEMENTS: { 8263 case NON_STRICT_ARGUMENTS_ELEMENTS: {
7974 // Aliased parameters and non-aliased elements in a fast backing store 8264 // Aliased parameters and non-aliased elements in a fast backing store
7975 // behave as FAST_ELEMENT. Non-aliased elements in a dictionary 8265 // behave as FAST_ELEMENT. Non-aliased elements in a dictionary
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
8040 switch (kind) { 8330 switch (kind) {
8041 case FAST_ELEMENTS: { 8331 case FAST_ELEMENTS: {
8042 uint32_t length = IsJSArray() ? 8332 uint32_t length = IsJSArray() ?
8043 static_cast<uint32_t> 8333 static_cast<uint32_t>
8044 (Smi::cast(JSArray::cast(this)->length())->value()) : 8334 (Smi::cast(JSArray::cast(this)->length())->value()) :
8045 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 8335 static_cast<uint32_t>(FixedArray::cast(elements())->length());
8046 if ((index < length) && 8336 if ((index < length) &&
8047 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; 8337 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
8048 break; 8338 break;
8049 } 8339 }
8340 case FAST_DOUBLE_ELEMENTS: {
8341 uint32_t length = IsJSArray() ?
8342 static_cast<uint32_t>
8343 (Smi::cast(JSArray::cast(this)->length())->value()) :
8344 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
8345 if ((index < length) &&
8346 !FixedDoubleArray::cast(elements())->is_the_hole(index)) return true;
8347 break;
8348 }
8050 case EXTERNAL_PIXEL_ELEMENTS: { 8349 case EXTERNAL_PIXEL_ELEMENTS: {
8051 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 8350 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
8052 if (index < static_cast<uint32_t>(pixels->length())) { 8351 if (index < static_cast<uint32_t>(pixels->length())) {
8053 return true; 8352 return true;
8054 } 8353 }
8055 break; 8354 break;
8056 } 8355 }
8057 case EXTERNAL_BYTE_ELEMENTS: 8356 case EXTERNAL_BYTE_ELEMENTS:
8058 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 8357 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
8059 case EXTERNAL_SHORT_ELEMENTS: 8358 case EXTERNAL_SHORT_ELEMENTS:
8060 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 8359 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
8061 case EXTERNAL_INT_ELEMENTS: 8360 case EXTERNAL_INT_ELEMENTS:
8062 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 8361 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
8063 case EXTERNAL_FLOAT_ELEMENTS: 8362 case EXTERNAL_FLOAT_ELEMENTS:
8064 case EXTERNAL_DOUBLE_ELEMENTS: { 8363 case EXTERNAL_DOUBLE_ELEMENTS: {
8065 ExternalArray* array = ExternalArray::cast(elements()); 8364 ExternalArray* array = ExternalArray::cast(elements());
8066 if (index < static_cast<uint32_t>(array->length())) { 8365 if (index < static_cast<uint32_t>(array->length())) {
8067 return true; 8366 return true;
8068 } 8367 }
8069 break; 8368 break;
8070 } 8369 }
8071 case FAST_DOUBLE_ELEMENTS:
8072 UNREACHABLE();
8073 break;
8074 case DICTIONARY_ELEMENTS: { 8370 case DICTIONARY_ELEMENTS: {
8075 if (element_dictionary()->FindEntry(index) 8371 if (element_dictionary()->FindEntry(index)
8076 != NumberDictionary::kNotFound) { 8372 != NumberDictionary::kNotFound) {
8077 return true; 8373 return true;
8078 } 8374 }
8079 break; 8375 break;
8080 } 8376 }
8081 case NON_STRICT_ARGUMENTS_ELEMENTS: { 8377 case NON_STRICT_ARGUMENTS_ELEMENTS: {
8082 FixedArray* parameter_map = FixedArray::cast(elements()); 8378 FixedArray* parameter_map = FixedArray::cast(elements());
8083 uint32_t length = parameter_map->length(); 8379 uint32_t length = parameter_map->length();
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
8316 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); 8612 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
8317 } 8613 }
8318 } 8614 }
8319 return value; 8615 return value;
8320 } 8616 }
8321 8617
8322 // Allow gap in fast case. 8618 // Allow gap in fast case.
8323 if ((index - length) < kMaxGap) { 8619 if ((index - length) < kMaxGap) {
8324 // Try allocating extra space. 8620 // Try allocating extra space.
8325 int new_capacity = NewElementsCapacity(index + 1); 8621 int new_capacity = NewElementsCapacity(index + 1);
8326 if (new_capacity <= kMaxFastElementsLength || 8622 if (!ShouldConvertToSlowElements(new_capacity)) {
8327 !ShouldConvertToSlowElements(new_capacity)) {
8328 ASSERT(static_cast<uint32_t>(new_capacity) > index); 8623 ASSERT(static_cast<uint32_t>(new_capacity) > index);
8329 Object* new_elements; 8624 Object* new_elements;
8330 MaybeObject* maybe = 8625 MaybeObject* maybe =
8331 SetFastElementsCapacityAndLength(new_capacity, index + 1); 8626 SetFastElementsCapacityAndLength(new_capacity, index + 1);
8332 if (!maybe->ToObject(&new_elements)) return maybe; 8627 if (!maybe->ToObject(&new_elements)) return maybe;
8333 FixedArray::cast(new_elements)->set(index, value); 8628 FixedArray::cast(new_elements)->set(index, value);
8334 return value; 8629 return value;
8335 } 8630 }
8336 } 8631 }
8337 8632
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
8425 } 8720 }
8426 8721
8427 // Attempt to put this object back in fast case. 8722 // Attempt to put this object back in fast case.
8428 if (ShouldConvertToFastElements()) { 8723 if (ShouldConvertToFastElements()) {
8429 uint32_t new_length = 0; 8724 uint32_t new_length = 0;
8430 if (IsJSArray()) { 8725 if (IsJSArray()) {
8431 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); 8726 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
8432 } else { 8727 } else {
8433 new_length = dictionary->max_number_key() + 1; 8728 new_length = dictionary->max_number_key() + 1;
8434 } 8729 }
8435 MaybeObject* result = 8730 MaybeObject* result = CanConvertToFastDoubleElements()
8436 SetFastElementsCapacityAndLength(new_length, new_length); 8731 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length)
8732 : SetFastElementsCapacityAndLength(new_length, new_length);
8437 if (result->IsFailure()) return result; 8733 if (result->IsFailure()) return result;
8438 #ifdef DEBUG 8734 #ifdef DEBUG
8439 if (FLAG_trace_normalization) { 8735 if (FLAG_trace_normalization) {
8440 PrintF("Object elements are fast case again:\n"); 8736 PrintF("Object elements are fast case again:\n");
8441 Print(); 8737 Print();
8442 } 8738 }
8443 #endif 8739 #endif
8444 } 8740 }
8445 return value; 8741 return value;
8446 } 8742 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
8498 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); 8794 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
8499 } 8795 }
8500 } 8796 }
8501 return value; 8797 return value;
8502 } 8798 }
8503 8799
8504 // Allow gap in fast case. 8800 // Allow gap in fast case.
8505 if ((index - elms_length) < kMaxGap) { 8801 if ((index - elms_length) < kMaxGap) {
8506 // Try allocating extra space. 8802 // Try allocating extra space.
8507 int new_capacity = NewElementsCapacity(index+1); 8803 int new_capacity = NewElementsCapacity(index+1);
8508 if (new_capacity <= kMaxFastElementsLength || 8804 if (!ShouldConvertToSlowElements(new_capacity)) {
8509 !ShouldConvertToSlowElements(new_capacity)) {
8510 ASSERT(static_cast<uint32_t>(new_capacity) > index); 8805 ASSERT(static_cast<uint32_t>(new_capacity) > index);
8511 Object* obj; 8806 Object* obj;
8512 { MaybeObject* maybe_obj = 8807 { MaybeObject* maybe_obj =
8513 SetFastDoubleElementsCapacityAndLength(new_capacity, 8808 SetFastDoubleElementsCapacityAndLength(new_capacity,
8514 index + 1); 8809 index + 1);
8515 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8810 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8516 } 8811 }
8517 FixedDoubleArray::cast(elements())->set(index, double_value); 8812 FixedDoubleArray::cast(elements())->set(index, double_value);
8518 return value; 8813 return value;
8519 } 8814 }
8520 } 8815 }
8521 8816
8522 // Otherwise default to slow case. 8817 // Otherwise default to slow case.
8818 ASSERT(HasFastDoubleElements());
8819 ASSERT(map()->has_fast_double_elements());
8820 ASSERT(elements()->IsFixedDoubleArray());
8523 Object* obj; 8821 Object* obj;
8524 { MaybeObject* maybe_obj = NormalizeElements(); 8822 { MaybeObject* maybe_obj = NormalizeElements();
8525 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8823 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8526 } 8824 }
8527 ASSERT(HasDictionaryElements()); 8825 ASSERT(HasDictionaryElements());
8528 return SetElement(index, value, strict_mode, check_prototype); 8826 return SetElement(index, value, strict_mode, check_prototype);
8529 } 8827 }
8530 8828
8531 8829
8532 MaybeObject* JSObject::SetElement(uint32_t index, 8830 MaybeObject* JSObject::SetElement(uint32_t index,
8533 Object* value, 8831 Object* value,
8534 StrictModeFlag strict_mode, 8832 StrictModeFlag strict_mode,
8535 bool check_prototype) { 8833 bool check_prototype) {
8536 // Check access rights if needed. 8834 // Check access rights if needed.
8537 if (IsAccessCheckNeeded()) { 8835 if (IsAccessCheckNeeded()) {
8538 Heap* heap = GetHeap(); 8836 Heap* heap = GetHeap();
8539 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { 8837 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) {
8540 HandleScope scope; 8838 HandleScope scope(heap->isolate());
8541 Handle<Object> value_handle(value); 8839 Handle<Object> value_handle(value);
8542 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); 8840 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET);
8543 return *value_handle; 8841 return *value_handle;
8544 } 8842 }
8545 } 8843 }
8546 8844
8547 if (IsJSGlobalProxy()) { 8845 if (IsJSGlobalProxy()) {
8548 Object* proto = GetPrototype(); 8846 Object* proto = GetPrototype();
8549 if (proto->IsNull()) return value; 8847 if (proto->IsNull()) return value;
8550 ASSERT(proto->IsJSGlobalObject()); 8848 ASSERT(proto->IsJSGlobalObject());
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
8964 case NON_STRICT_ARGUMENTS_ELEMENTS: 9262 case NON_STRICT_ARGUMENTS_ELEMENTS:
8965 UNIMPLEMENTED(); 9263 UNIMPLEMENTED();
8966 break; 9264 break;
8967 } 9265 }
8968 return GetHeap()->undefined_value(); 9266 return GetHeap()->undefined_value();
8969 } 9267 }
8970 9268
8971 9269
8972 bool JSObject::HasDenseElements() { 9270 bool JSObject::HasDenseElements() {
8973 int capacity = 0; 9271 int capacity = 0;
8974 int number_of_elements = 0; 9272 int used = 0;
9273 GetElementsCapacityAndUsage(&capacity, &used);
9274 return (capacity == 0) || (used > (capacity / 2));
9275 }
8975 9276
8976 FixedArray* backing_store = FixedArray::cast(elements()); 9277
9278 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
9279 *capacity = 0;
9280 *used = 0;
9281
9282 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements());
9283 FixedArray* backing_store = NULL;
8977 switch (GetElementsKind()) { 9284 switch (GetElementsKind()) {
8978 case NON_STRICT_ARGUMENTS_ELEMENTS: 9285 case NON_STRICT_ARGUMENTS_ELEMENTS:
8979 backing_store = FixedArray::cast(backing_store->get(1)); 9286 backing_store_base =
9287 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
9288 backing_store = FixedArray::cast(backing_store_base);
8980 if (backing_store->IsDictionary()) { 9289 if (backing_store->IsDictionary()) {
8981 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); 9290 NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
8982 capacity = dictionary->Capacity(); 9291 *capacity = dictionary->Capacity();
8983 number_of_elements = dictionary->NumberOfElements(); 9292 *used = dictionary->NumberOfElements();
8984 break; 9293 break;
8985 } 9294 }
8986 // Fall through. 9295 // Fall through.
8987 case FAST_ELEMENTS: 9296 case FAST_ELEMENTS:
8988 capacity = backing_store->length(); 9297 backing_store = FixedArray::cast(backing_store_base);
8989 for (int i = 0; i < capacity; ++i) { 9298 *capacity = backing_store->length();
8990 if (!backing_store->get(i)->IsTheHole()) ++number_of_elements; 9299 for (int i = 0; i < *capacity; ++i) {
9300 if (!backing_store->get(i)->IsTheHole()) ++(*used);
8991 } 9301 }
8992 break; 9302 break;
8993 case DICTIONARY_ELEMENTS: { 9303 case DICTIONARY_ELEMENTS: {
8994 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); 9304 NumberDictionary* dictionary =
8995 capacity = dictionary->Capacity(); 9305 NumberDictionary::cast(FixedArray::cast(elements()));
8996 number_of_elements = dictionary->NumberOfElements(); 9306 *capacity = dictionary->Capacity();
9307 *used = dictionary->NumberOfElements();
8997 break; 9308 break;
8998 } 9309 }
8999 case FAST_DOUBLE_ELEMENTS: { 9310 case FAST_DOUBLE_ELEMENTS: {
9000 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); 9311 FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
9001 capacity = elms->length(); 9312 *capacity = elms->length();
9002 for (int i = 0; i < capacity; i++) { 9313 for (int i = 0; i < *capacity; i++) {
9003 if (!elms->is_the_hole(i)) number_of_elements++; 9314 if (!elms->is_the_hole(i)) ++(*used);
9004 } 9315 }
9005 break; 9316 break;
9006 } 9317 }
9007 case EXTERNAL_PIXEL_ELEMENTS:
9008 case EXTERNAL_BYTE_ELEMENTS: 9318 case EXTERNAL_BYTE_ELEMENTS:
9009 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 9319 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
9010 case EXTERNAL_SHORT_ELEMENTS: 9320 case EXTERNAL_SHORT_ELEMENTS:
9011 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 9321 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
9012 case EXTERNAL_INT_ELEMENTS: 9322 case EXTERNAL_INT_ELEMENTS:
9013 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 9323 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
9014 case EXTERNAL_FLOAT_ELEMENTS: 9324 case EXTERNAL_FLOAT_ELEMENTS:
9015 case EXTERNAL_DOUBLE_ELEMENTS: { 9325 case EXTERNAL_DOUBLE_ELEMENTS:
9016 return true; 9326 case EXTERNAL_PIXEL_ELEMENTS:
9017 } 9327 // External arrays are considered 100% used.
9328 ExternalArray* external_array = ExternalArray::cast(elements());
9329 *capacity = external_array->length();
9330 *used = external_array->length();
9331 break;
9018 } 9332 }
9019 return (capacity == 0) || (number_of_elements > (capacity / 2));
9020 } 9333 }
9021 9334
9022 9335
9023 bool JSObject::ShouldConvertToSlowElements(int new_capacity) { 9336 bool JSObject::ShouldConvertToSlowElements(int new_capacity) {
9024 // Keep the array in fast case if the current backing storage is 9337 STATIC_ASSERT(kMaxUncheckedOldFastElementsLength <=
9025 // almost filled and if the new capacity is no more than twice the 9338 kMaxUncheckedFastElementsLength);
9026 // old capacity. 9339 if (new_capacity <= kMaxUncheckedOldFastElementsLength ||
9027 int elements_length = 0; 9340 (new_capacity <= kMaxUncheckedFastElementsLength &&
9028 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { 9341 GetHeap()->InNewSpace(this))) {
9029 FixedArray* backing_store = FixedArray::cast(elements()); 9342 return false;
9030 elements_length = FixedArray::cast(backing_store->get(1))->length();
9031 } else if (HasFastElements()) {
9032 elements_length = FixedArray::cast(elements())->length();
9033 } else if (HasFastDoubleElements()) {
9034 elements_length = FixedDoubleArray::cast(elements())->length();
9035 } else {
9036 UNREACHABLE();
9037 } 9343 }
9038 return !HasDenseElements() || ((new_capacity / 2) > elements_length); 9344 // If the fast-case backing storage takes up roughly three times as
9345 // much space (in machine words) as a dictionary backing storage
9346 // would, the object should have slow elements.
9347 int old_capacity = 0;
9348 int used_elements = 0;
9349 GetElementsCapacityAndUsage(&old_capacity, &used_elements);
9350 int dictionary_size = NumberDictionary::ComputeCapacity(used_elements) *
9351 NumberDictionary::kEntrySize;
9352 return 3 * dictionary_size <= new_capacity;
9039 } 9353 }
9040 9354
9041 9355
9042 bool JSObject::ShouldConvertToFastElements() { 9356 bool JSObject::ShouldConvertToFastElements() {
9043 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 9357 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
9044 // If the elements are sparse, we should not go back to fast case. 9358 // If the elements are sparse, we should not go back to fast case.
9045 if (!HasDenseElements()) return false; 9359 if (!HasDenseElements()) return false;
9046 // An object requiring access checks is never allowed to have fast 9360 // An object requiring access checks is never allowed to have fast
9047 // elements. If it had fast elements we would skip security checks. 9361 // elements. If it had fast elements we would skip security checks.
9048 if (IsAccessCheckNeeded()) return false; 9362 if (IsAccessCheckNeeded()) return false;
9049 9363
9050 FixedArray* elements = FixedArray::cast(this->elements()); 9364 FixedArray* elements = FixedArray::cast(this->elements());
9051 NumberDictionary* dictionary = NULL; 9365 NumberDictionary* dictionary = NULL;
9052 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { 9366 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) {
9053 dictionary = NumberDictionary::cast(elements->get(1)); 9367 dictionary = NumberDictionary::cast(elements->get(1));
9054 } else { 9368 } else {
9055 dictionary = NumberDictionary::cast(elements); 9369 dictionary = NumberDictionary::cast(elements);
9056 } 9370 }
9057 // If an element has been added at a very high index in the elements 9371 // If an element has been added at a very high index in the elements
9058 // dictionary, we cannot go back to fast case. 9372 // dictionary, we cannot go back to fast case.
9059 if (dictionary->requires_slow_elements()) return false; 9373 if (dictionary->requires_slow_elements()) return false;
9060 // If the dictionary backing storage takes up roughly half as much 9374 // If the dictionary backing storage takes up roughly half as much
9061 // space as a fast-case backing storage would the array should have 9375 // space (in machine words) as a fast-case backing storage would,
9062 // fast elements. 9376 // the object should have fast elements.
9063 uint32_t length = 0; 9377 uint32_t array_size = 0;
9064 if (IsJSArray()) { 9378 if (IsJSArray()) {
9065 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); 9379 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size));
9066 } else { 9380 } else {
9067 length = dictionary->max_number_key(); 9381 array_size = dictionary->max_number_key();
9068 } 9382 }
9069 return static_cast<uint32_t>(dictionary->Capacity()) >= 9383 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) *
9070 (length / (2 * NumberDictionary::kEntrySize)); 9384 NumberDictionary::kEntrySize;
9385 return 2 * dictionary_size >= array_size;
9071 } 9386 }
9072 9387
9073 9388
9074 bool JSObject::ShouldConvertToFastDoubleElements() { 9389 bool JSObject::CanConvertToFastDoubleElements() {
9075 if (FLAG_unbox_double_arrays) { 9390 if (FLAG_unbox_double_arrays) {
9076 ASSERT(HasDictionaryElements()); 9391 ASSERT(HasDictionaryElements());
9077 NumberDictionary* dictionary = NumberDictionary::cast(elements()); 9392 NumberDictionary* dictionary = NumberDictionary::cast(elements());
9078 for (int i = 0; i < dictionary->Capacity(); i++) { 9393 for (int i = 0; i < dictionary->Capacity(); i++) {
9079 Object* key = dictionary->KeyAt(i); 9394 Object* key = dictionary->KeyAt(i);
9080 if (key->IsNumber()) { 9395 if (key->IsNumber()) {
9081 if (!dictionary->ValueAt(i)->IsNumber()) return false; 9396 if (!dictionary->ValueAt(i)->IsNumber()) return false;
9082 } 9397 }
9083 } 9398 }
9084 return true; 9399 return true;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
9254 9569
9255 switch (GetElementsKind()) { 9570 switch (GetElementsKind()) {
9256 case FAST_ELEMENTS: { 9571 case FAST_ELEMENTS: {
9257 uint32_t length = IsJSArray() ? 9572 uint32_t length = IsJSArray() ?
9258 static_cast<uint32_t>( 9573 static_cast<uint32_t>(
9259 Smi::cast(JSArray::cast(this)->length())->value()) : 9574 Smi::cast(JSArray::cast(this)->length())->value()) :
9260 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 9575 static_cast<uint32_t>(FixedArray::cast(elements())->length());
9261 return (index < length) && 9576 return (index < length) &&
9262 !FixedArray::cast(elements())->get(index)->IsTheHole(); 9577 !FixedArray::cast(elements())->get(index)->IsTheHole();
9263 } 9578 }
9579 case FAST_DOUBLE_ELEMENTS: {
9580 uint32_t length = IsJSArray() ?
9581 static_cast<uint32_t>(
9582 Smi::cast(JSArray::cast(this)->length())->value()) :
9583 static_cast<uint32_t>(FixedDoubleArray::cast(elements())->length());
9584 return (index < length) &&
9585 !FixedDoubleArray::cast(elements())->is_the_hole(index);
9586 break;
9587 }
9264 case EXTERNAL_PIXEL_ELEMENTS: { 9588 case EXTERNAL_PIXEL_ELEMENTS: {
9265 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 9589 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
9266 return index < static_cast<uint32_t>(pixels->length()); 9590 return index < static_cast<uint32_t>(pixels->length());
9267 } 9591 }
9268 case EXTERNAL_BYTE_ELEMENTS: 9592 case EXTERNAL_BYTE_ELEMENTS:
9269 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 9593 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
9270 case EXTERNAL_SHORT_ELEMENTS: 9594 case EXTERNAL_SHORT_ELEMENTS:
9271 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 9595 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
9272 case EXTERNAL_INT_ELEMENTS: 9596 case EXTERNAL_INT_ELEMENTS:
9273 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 9597 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
9274 case EXTERNAL_FLOAT_ELEMENTS: 9598 case EXTERNAL_FLOAT_ELEMENTS:
9275 case EXTERNAL_DOUBLE_ELEMENTS: { 9599 case EXTERNAL_DOUBLE_ELEMENTS: {
9276 ExternalArray* array = ExternalArray::cast(elements()); 9600 ExternalArray* array = ExternalArray::cast(elements());
9277 return index < static_cast<uint32_t>(array->length()); 9601 return index < static_cast<uint32_t>(array->length());
9278 } 9602 }
9279 case FAST_DOUBLE_ELEMENTS:
9280 UNREACHABLE();
9281 break;
9282 case DICTIONARY_ELEMENTS: { 9603 case DICTIONARY_ELEMENTS: {
9283 return element_dictionary()->FindEntry(index) 9604 return element_dictionary()->FindEntry(index)
9284 != NumberDictionary::kNotFound; 9605 != NumberDictionary::kNotFound;
9285 } 9606 }
9286 case NON_STRICT_ARGUMENTS_ELEMENTS: 9607 case NON_STRICT_ARGUMENTS_ELEMENTS:
9287 UNIMPLEMENTED(); 9608 UNIMPLEMENTED();
9288 break; 9609 break;
9289 } 9610 }
9290 // All possibilities have been handled above already. 9611 // All possibilities have been handled above already.
9291 UNREACHABLE(); 9612 UNREACHABLE();
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
9492 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { 9813 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) {
9493 if (storage != NULL) { 9814 if (storage != NULL) {
9494 storage->set(counter, Smi::FromInt(i)); 9815 storage->set(counter, Smi::FromInt(i));
9495 } 9816 }
9496 counter++; 9817 counter++;
9497 } 9818 }
9498 } 9819 }
9499 ASSERT(!storage || storage->length() >= counter); 9820 ASSERT(!storage || storage->length() >= counter);
9500 break; 9821 break;
9501 } 9822 }
9823 case FAST_DOUBLE_ELEMENTS: {
9824 int length = IsJSArray() ?
9825 Smi::cast(JSArray::cast(this)->length())->value() :
9826 FixedDoubleArray::cast(elements())->length();
9827 for (int i = 0; i < length; i++) {
9828 if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) {
9829 if (storage != NULL) {
9830 storage->set(counter, Smi::FromInt(i));
9831 }
9832 counter++;
9833 }
9834 }
9835 ASSERT(!storage || storage->length() >= counter);
9836 break;
9837 }
9502 case EXTERNAL_PIXEL_ELEMENTS: { 9838 case EXTERNAL_PIXEL_ELEMENTS: {
9503 int length = ExternalPixelArray::cast(elements())->length(); 9839 int length = ExternalPixelArray::cast(elements())->length();
9504 while (counter < length) { 9840 while (counter < length) {
9505 if (storage != NULL) { 9841 if (storage != NULL) {
9506 storage->set(counter, Smi::FromInt(counter)); 9842 storage->set(counter, Smi::FromInt(counter));
9507 } 9843 }
9508 counter++; 9844 counter++;
9509 } 9845 }
9510 ASSERT(!storage || storage->length() >= counter); 9846 ASSERT(!storage || storage->length() >= counter);
9511 break; 9847 break;
9512 } 9848 }
9513 case EXTERNAL_BYTE_ELEMENTS: 9849 case EXTERNAL_BYTE_ELEMENTS:
9514 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 9850 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
9515 case EXTERNAL_SHORT_ELEMENTS: 9851 case EXTERNAL_SHORT_ELEMENTS:
9516 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 9852 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
9517 case EXTERNAL_INT_ELEMENTS: 9853 case EXTERNAL_INT_ELEMENTS:
9518 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 9854 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
9519 case EXTERNAL_FLOAT_ELEMENTS: 9855 case EXTERNAL_FLOAT_ELEMENTS:
9520 case EXTERNAL_DOUBLE_ELEMENTS: { 9856 case EXTERNAL_DOUBLE_ELEMENTS: {
9521 int length = ExternalArray::cast(elements())->length(); 9857 int length = ExternalArray::cast(elements())->length();
9522 while (counter < length) { 9858 while (counter < length) {
9523 if (storage != NULL) { 9859 if (storage != NULL) {
9524 storage->set(counter, Smi::FromInt(counter)); 9860 storage->set(counter, Smi::FromInt(counter));
9525 } 9861 }
9526 counter++; 9862 counter++;
9527 } 9863 }
9528 ASSERT(!storage || storage->length() >= counter); 9864 ASSERT(!storage || storage->length() >= counter);
9529 break; 9865 break;
9530 } 9866 }
9531 case FAST_DOUBLE_ELEMENTS:
9532 UNREACHABLE();
9533 break;
9534 case DICTIONARY_ELEMENTS: { 9867 case DICTIONARY_ELEMENTS: {
9535 if (storage != NULL) { 9868 if (storage != NULL) {
9536 element_dictionary()->CopyKeysTo(storage, 9869 element_dictionary()->CopyKeysTo(storage,
9537 filter, 9870 filter,
9538 NumberDictionary::SORTED); 9871 NumberDictionary::SORTED);
9539 } 9872 }
9540 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); 9873 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
9541 break; 9874 break;
9542 } 9875 }
9543 case NON_STRICT_ARGUMENTS_ELEMENTS: { 9876 case NON_STRICT_ARGUMENTS_ELEMENTS: {
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
9977 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { 10310 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) {
9978 IteratePointers(v, 10311 IteratePointers(v,
9979 kElementsStartOffset, 10312 kElementsStartOffset,
9980 kHeaderSize + length() * kPointerSize); 10313 kHeaderSize + length() * kPointerSize);
9981 } 10314 }
9982 10315
9983 10316
9984 template<typename Shape, typename Key> 10317 template<typename Shape, typename Key>
9985 MaybeObject* HashTable<Shape, Key>::Allocate(int at_least_space_for, 10318 MaybeObject* HashTable<Shape, Key>::Allocate(int at_least_space_for,
9986 PretenureFlag pretenure) { 10319 PretenureFlag pretenure) {
9987 const int kMinCapacity = 32; 10320 int capacity = ComputeCapacity(at_least_space_for);
9988 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); 10321 if (capacity > HashTable::kMaxCapacity) {
9989 if (capacity < kMinCapacity) {
9990 capacity = kMinCapacity; // Guarantee min capacity.
9991 } else if (capacity > HashTable::kMaxCapacity) {
9992 return Failure::OutOfMemoryException(); 10322 return Failure::OutOfMemoryException();
9993 } 10323 }
9994 10324
9995 Object* obj; 10325 Object* obj;
9996 { MaybeObject* maybe_obj = Isolate::Current()->heap()-> 10326 { MaybeObject* maybe_obj = Isolate::Current()->heap()->
9997 AllocateHashTable(EntryToIndex(capacity), pretenure); 10327 AllocateHashTable(EntryToIndex(capacity), pretenure);
9998 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10328 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
9999 } 10329 }
10000 HashTable::cast(obj)->SetNumberOfElements(0); 10330 HashTable::cast(obj)->SetNumberOfElements(0);
10001 HashTable::cast(obj)->SetNumberOfDeletedElements(0); 10331 HashTable::cast(obj)->SetNumberOfDeletedElements(0);
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
10149 10479
10150 // Force instantiation of template instances class. 10480 // Force instantiation of template instances class.
10151 // Please note this list is compiler dependent. 10481 // Please note this list is compiler dependent.
10152 10482
10153 template class HashTable<SymbolTableShape, HashTableKey*>; 10483 template class HashTable<SymbolTableShape, HashTableKey*>;
10154 10484
10155 template class HashTable<CompilationCacheShape, HashTableKey*>; 10485 template class HashTable<CompilationCacheShape, HashTableKey*>;
10156 10486
10157 template class HashTable<MapCacheShape, HashTableKey*>; 10487 template class HashTable<MapCacheShape, HashTableKey*>;
10158 10488
10489 template class HashTable<ObjectHashTableShape, JSObject*>;
10490
10159 template class Dictionary<StringDictionaryShape, String*>; 10491 template class Dictionary<StringDictionaryShape, String*>;
10160 10492
10161 template class Dictionary<NumberDictionaryShape, uint32_t>; 10493 template class Dictionary<NumberDictionaryShape, uint32_t>;
10162 10494
10163 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( 10495 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate(
10164 int); 10496 int);
10165 10497
10166 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( 10498 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate(
10167 int); 10499 int);
10168 10500
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after
11071 } 11403 }
11072 } 11404 }
11073 11405
11074 // Update the number of elements. 11406 // Update the number of elements.
11075 ElementsRemoved(removed_entries); 11407 ElementsRemoved(removed_entries);
11076 } 11408 }
11077 11409
11078 11410
11079 template<typename Shape, typename Key> 11411 template<typename Shape, typename Key>
11080 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, 11412 Object* Dictionary<Shape, Key>::DeleteProperty(int entry,
11081 JSObject::DeleteMode mode) { 11413 JSReceiver::DeleteMode mode) {
11082 Heap* heap = Dictionary<Shape, Key>::GetHeap(); 11414 Heap* heap = Dictionary<Shape, Key>::GetHeap();
11083 PropertyDetails details = DetailsAt(entry); 11415 PropertyDetails details = DetailsAt(entry);
11084 // Ignore attributes if forcing a deletion. 11416 // Ignore attributes if forcing a deletion.
11085 if (details.IsDontDelete() && mode != JSObject::FORCE_DELETION) { 11417 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) {
11086 return heap->false_value(); 11418 return heap->false_value();
11087 } 11419 }
11088 SetEntry(entry, heap->null_value(), heap->null_value()); 11420 SetEntry(entry, heap->null_value(), heap->null_value());
11089 HashTable<Shape, Key>::ElementRemoved(); 11421 HashTable<Shape, Key>::ElementRemoved();
11090 return heap->true_value(); 11422 return heap->true_value();
11091 } 11423 }
11092 11424
11093 11425
11094 template<typename Shape, typename Key> 11426 template<typename Shape, typename Key>
11095 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) { 11427 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) {
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
11460 ASSERT(obj->IsJSObject()); 11792 ASSERT(obj->IsJSObject());
11461 11793
11462 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); 11794 descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
11463 // Check that it really works. 11795 // Check that it really works.
11464 ASSERT(obj->HasFastProperties()); 11796 ASSERT(obj->HasFastProperties());
11465 11797
11466 return obj; 11798 return obj;
11467 } 11799 }
11468 11800
11469 11801
11802 Object* ObjectHashTable::Lookup(JSObject* key) {
11803 // If the object does not have an identity hash, it was never used as a key.
11804 MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::OMIT_CREATION);
11805 if (maybe_hash->IsFailure()) return GetHeap()->undefined_value();
11806 int entry = FindEntry(key);
11807 if (entry == kNotFound) return GetHeap()->undefined_value();
11808 return get(EntryToIndex(entry) + 1);
11809 }
11810
11811
11812 MaybeObject* ObjectHashTable::Put(JSObject* key, Object* value) {
11813 // Make sure the key object has an identity hash code.
11814 int hash;
11815 { MaybeObject* maybe_hash = key->GetIdentityHash(JSObject::ALLOW_CREATION);
11816 if (maybe_hash->IsFailure()) return maybe_hash;
11817 hash = Smi::cast(maybe_hash->ToObjectUnchecked())->value();
11818 }
11819 int entry = FindEntry(key);
11820
11821 // Check whether to perform removal operation.
11822 if (value->IsUndefined()) {
11823 if (entry == kNotFound) return this;
11824 RemoveEntry(entry);
11825 return Shrink(key);
11826 }
11827
11828 // Key is already in table, just overwrite value.
11829 if (entry != kNotFound) {
11830 set(EntryToIndex(entry) + 1, value);
11831 return this;
11832 }
11833
11834 // Check whether the hash table should be extended.
11835 Object* obj;
11836 { MaybeObject* maybe_obj = EnsureCapacity(1, key);
11837 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
11838 }
11839 ObjectHashTable* table = ObjectHashTable::cast(obj);
11840 table->AddEntry(table->FindInsertionEntry(hash), key, value);
11841 return table;
11842 }
11843
11844
11845 void ObjectHashTable::AddEntry(int entry, JSObject* key, Object* value) {
11846 set(EntryToIndex(entry), key);
11847 set(EntryToIndex(entry) + 1, value);
11848 ElementAdded();
11849 }
11850
11851
11852 void ObjectHashTable::RemoveEntry(int entry) {
11853 Object* null_value = GetHeap()->null_value();
11854 set(EntryToIndex(entry), null_value);
11855 set(EntryToIndex(entry) + 1, null_value);
11856 ElementRemoved();
11857 }
11858
11859
11470 #ifdef ENABLE_DEBUGGER_SUPPORT 11860 #ifdef ENABLE_DEBUGGER_SUPPORT
11471 // Check if there is a break point at this code position. 11861 // Check if there is a break point at this code position.
11472 bool DebugInfo::HasBreakPoint(int code_position) { 11862 bool DebugInfo::HasBreakPoint(int code_position) {
11473 // Get the break point info object for this code position. 11863 // Get the break point info object for this code position.
11474 Object* break_point_info = GetBreakPointInfo(code_position); 11864 Object* break_point_info = GetBreakPointInfo(code_position);
11475 11865
11476 // If there is no break point info object or no break points in the break 11866 // If there is no break point info object or no break points in the break
11477 // point info object there is no break point at this code position. 11867 // point info object there is no break point at this code position.
11478 if (break_point_info->IsUndefined()) return false; 11868 if (break_point_info->IsUndefined()) return false;
11479 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; 11869 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0;
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
11714 if (break_point_objects()->IsUndefined()) return 0; 12104 if (break_point_objects()->IsUndefined()) return 0;
11715 // Single beak point. 12105 // Single beak point.
11716 if (!break_point_objects()->IsFixedArray()) return 1; 12106 if (!break_point_objects()->IsFixedArray()) return 1;
11717 // Multiple break points. 12107 // Multiple break points.
11718 return FixedArray::cast(break_point_objects())->length(); 12108 return FixedArray::cast(break_point_objects())->length();
11719 } 12109 }
11720 #endif 12110 #endif
11721 12111
11722 12112
11723 } } // namespace v8::internal 12113 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698