OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 // Add the constant properties to the boilerplate. | 244 // Add the constant properties to the boilerplate. |
245 int length = constant_properties->length(); | 245 int length = constant_properties->length(); |
246 bool should_transform = | 246 bool should_transform = |
247 !is_result_from_cache && boilerplate->HasFastProperties(); | 247 !is_result_from_cache && boilerplate->HasFastProperties(); |
248 bool should_normalize = should_transform || has_function_literal; | 248 bool should_normalize = should_transform || has_function_literal; |
249 if (should_normalize) { | 249 if (should_normalize) { |
250 // TODO(verwaest): We might not want to ever normalize here. | 250 // TODO(verwaest): We might not want to ever normalize here. |
251 JSObject::NormalizeProperties( | 251 JSObject::NormalizeProperties( |
252 boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2); | 252 boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2); |
253 } | 253 } |
254 Object::ValueType value_type = should_normalize | |
255 ? Object::FORCE_TAGGED : Object::OPTIMAL_REPRESENTATION; | |
256 | |
257 // TODO(verwaest): Support tracking representations in the boilerplate. | 254 // TODO(verwaest): Support tracking representations in the boilerplate. |
258 for (int index = 0; index < length; index +=2) { | 255 for (int index = 0; index < length; index +=2) { |
259 Handle<Object> key(constant_properties->get(index+0), isolate); | 256 Handle<Object> key(constant_properties->get(index+0), isolate); |
260 Handle<Object> value(constant_properties->get(index+1), isolate); | 257 Handle<Object> value(constant_properties->get(index+1), isolate); |
261 if (value->IsFixedArray()) { | 258 if (value->IsFixedArray()) { |
262 // The value contains the constant_properties of a | 259 // The value contains the constant_properties of a |
263 // simple object or array literal. | 260 // simple object or array literal. |
264 Handle<FixedArray> array = Handle<FixedArray>::cast(value); | 261 Handle<FixedArray> array = Handle<FixedArray>::cast(value); |
265 ASSIGN_RETURN_ON_EXCEPTION( | 262 ASSIGN_RETURN_ON_EXCEPTION( |
266 isolate, value, | 263 isolate, value, |
267 CreateLiteralBoilerplate(isolate, literals, array), | 264 CreateLiteralBoilerplate(isolate, literals, array), |
268 Object); | 265 Object); |
269 } | 266 } |
270 MaybeHandle<Object> maybe_result; | 267 MaybeHandle<Object> maybe_result; |
271 uint32_t element_index = 0; | 268 uint32_t element_index = 0; |
272 StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT; | 269 StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT; |
273 if (key->IsInternalizedString()) { | 270 if (key->IsInternalizedString()) { |
274 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { | 271 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { |
275 // Array index as string (uint32). | 272 // Array index as string (uint32). |
276 if (value->IsUninitialized()) { | 273 if (value->IsUninitialized()) { |
277 maybe_result = value; | 274 maybe_result = value; |
278 } else { | 275 } else { |
279 maybe_result = JSObject::SetOwnElement( | 276 maybe_result = JSObject::SetOwnElement( |
280 boilerplate, element_index, value, SLOPPY); | 277 boilerplate, element_index, value, SLOPPY); |
281 } | 278 } |
282 } else { | 279 } else { |
283 Handle<String> name(String::cast(*key)); | 280 Handle<String> name(String::cast(*key)); |
284 ASSERT(!name->AsArrayIndex(&element_index)); | 281 ASSERT(!name->AsArrayIndex(&element_index)); |
285 maybe_result = JSObject::SetOwnPropertyIgnoreAttributes( | 282 maybe_result = JSObject::SetOwnPropertyIgnoreAttributes( |
286 boilerplate, name, value, NONE, | 283 boilerplate, name, value, NONE, mode); |
287 value_type, mode); | |
288 } | 284 } |
289 } else if (key->ToArrayIndex(&element_index)) { | 285 } else if (key->ToArrayIndex(&element_index)) { |
290 // Array index (uint32). | 286 // Array index (uint32). |
291 if (value->IsUninitialized()) { | 287 if (value->IsUninitialized()) { |
292 maybe_result = value; | 288 maybe_result = value; |
293 } else { | 289 } else { |
294 maybe_result = JSObject::SetOwnElement( | 290 maybe_result = JSObject::SetOwnElement( |
295 boilerplate, element_index, value, SLOPPY); | 291 boilerplate, element_index, value, SLOPPY); |
296 } | 292 } |
297 } else { | 293 } else { |
298 // Non-uint32 number. | 294 // Non-uint32 number. |
299 ASSERT(key->IsNumber()); | 295 ASSERT(key->IsNumber()); |
300 double num = key->Number(); | 296 double num = key->Number(); |
301 char arr[100]; | 297 char arr[100]; |
302 Vector<char> buffer(arr, ARRAY_SIZE(arr)); | 298 Vector<char> buffer(arr, ARRAY_SIZE(arr)); |
303 const char* str = DoubleToCString(num, buffer); | 299 const char* str = DoubleToCString(num, buffer); |
304 Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str); | 300 Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str); |
305 maybe_result = JSObject::SetOwnPropertyIgnoreAttributes( | 301 maybe_result = JSObject::SetOwnPropertyIgnoreAttributes( |
306 boilerplate, name, value, NONE, value_type, mode); | 302 boilerplate, name, value, NONE, mode); |
307 } | 303 } |
308 // If setting the property on the boilerplate throws an | 304 // If setting the property on the boilerplate throws an |
309 // exception, the exception is converted to an empty handle in | 305 // exception, the exception is converted to an empty handle in |
310 // the handle based operations. In that case, we need to | 306 // the handle based operations. In that case, we need to |
311 // convert back to an exception. | 307 // convert back to an exception. |
312 RETURN_ON_EXCEPTION(isolate, maybe_result, Object); | 308 RETURN_ON_EXCEPTION(isolate, maybe_result, Object); |
313 } | 309 } |
314 | 310 |
315 // Transform to fast properties if necessary. For object literals with | 311 // Transform to fast properties if necessary. For object literals with |
316 // containing function literals we defer this operation until after all | 312 // containing function literals we defer this operation until after all |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 ASSIGN_RETURN_ON_EXCEPTION( | 561 ASSIGN_RETURN_ON_EXCEPTION( |
566 isolate, site, | 562 isolate, site, |
567 GetLiteralAllocationSite(isolate, literals, literals_index, elements), | 563 GetLiteralAllocationSite(isolate, literals, literals_index, elements), |
568 JSObject); | 564 JSObject); |
569 | 565 |
570 bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; | 566 bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; |
571 Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); | 567 Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); |
572 AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); | 568 AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); |
573 usage_context.EnterNewScope(); | 569 usage_context.EnterNewScope(); |
574 JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0 | 570 JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0 |
575 ? JSObject::kNoHints | 571 ? JSObject::kNoHints |
576 : JSObject::kObjectIsShallowArray; | 572 : JSObject::kObjectIsShallow; |
577 MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context, | 573 MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context, |
578 hints); | 574 hints); |
579 usage_context.ExitScope(site, boilerplate); | 575 usage_context.ExitScope(site, boilerplate); |
580 return copy; | 576 return copy; |
581 } | 577 } |
582 | 578 |
583 | 579 |
584 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { | 580 RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { |
585 HandleScope scope(isolate); | 581 HandleScope scope(isolate); |
586 ASSERT(args.length() == 4); | 582 ASSERT(args.length() == 4); |
(...skipping 4499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5086 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 5082 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
5087 } | 5083 } |
5088 | 5084 |
5089 // Use IgnoreAttributes version since a readonly property may be | 5085 // Use IgnoreAttributes version since a readonly property may be |
5090 // overridden and SetProperty does not allow this. | 5086 // overridden and SetProperty does not allow this. |
5091 Handle<Object> result; | 5087 Handle<Object> result; |
5092 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5088 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5093 isolate, result, | 5089 isolate, result, |
5094 JSObject::SetOwnPropertyIgnoreAttributes( | 5090 JSObject::SetOwnPropertyIgnoreAttributes( |
5095 js_object, name, obj_value, attr, | 5091 js_object, name, obj_value, attr, |
5096 Object::OPTIMAL_REPRESENTATION, | |
5097 ALLOW_AS_CONSTANT, | 5092 ALLOW_AS_CONSTANT, |
5098 JSReceiver::PERFORM_EXTENSIBILITY_CHECK, | 5093 JSReceiver::PERFORM_EXTENSIBILITY_CHECK, |
5099 JSReceiver::MAY_BE_STORE_FROM_KEYED, | 5094 JSReceiver::MAY_BE_STORE_FROM_KEYED, |
5100 JSObject::DONT_FORCE_FIELD)); | 5095 JSObject::DONT_FORCE_FIELD)); |
5101 return *result; | 5096 return *result; |
5102 } | 5097 } |
5103 | 5098 |
5104 Handle<Object> result; | 5099 Handle<Object> result; |
5105 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5100 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5106 isolate, result, | 5101 isolate, result, |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5242 } | 5237 } |
5243 | 5238 |
5244 if (key->IsName()) { | 5239 if (key->IsName()) { |
5245 Handle<Name> name = Handle<Name>::cast(key); | 5240 Handle<Name> name = Handle<Name>::cast(key); |
5246 if (name->AsArrayIndex(&index)) { | 5241 if (name->AsArrayIndex(&index)) { |
5247 return JSObject::SetElement(js_object, index, value, attr, | 5242 return JSObject::SetElement(js_object, index, value, attr, |
5248 SLOPPY, false, DEFINE_PROPERTY); | 5243 SLOPPY, false, DEFINE_PROPERTY); |
5249 } else { | 5244 } else { |
5250 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 5245 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
5251 return JSObject::SetOwnPropertyIgnoreAttributes( | 5246 return JSObject::SetOwnPropertyIgnoreAttributes( |
5252 js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION, | 5247 js_object, name, value, attr, ALLOW_AS_CONSTANT, |
5253 ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK, | 5248 JSReceiver::PERFORM_EXTENSIBILITY_CHECK, store_from_keyed); |
5254 store_from_keyed); | |
5255 } | 5249 } |
5256 } | 5250 } |
5257 | 5251 |
5258 // Call-back into JavaScript to convert the key to a string. | 5252 // Call-back into JavaScript to convert the key to a string. |
5259 Handle<Object> converted; | 5253 Handle<Object> converted; |
5260 ASSIGN_RETURN_ON_EXCEPTION( | 5254 ASSIGN_RETURN_ON_EXCEPTION( |
5261 isolate, converted, Execution::ToString(isolate, key), Object); | 5255 isolate, converted, Execution::ToString(isolate, key), Object); |
5262 Handle<String> name = Handle<String>::cast(converted); | 5256 Handle<String> name = Handle<String>::cast(converted); |
5263 | 5257 |
5264 if (name->AsArrayIndex(&index)) { | 5258 if (name->AsArrayIndex(&index)) { |
5265 return JSObject::SetElement(js_object, index, value, attr, | 5259 return JSObject::SetElement(js_object, index, value, attr, |
5266 SLOPPY, false, DEFINE_PROPERTY); | 5260 SLOPPY, false, DEFINE_PROPERTY); |
5267 } else { | 5261 } else { |
5268 return JSObject::SetOwnPropertyIgnoreAttributes( | 5262 return JSObject::SetOwnPropertyIgnoreAttributes( |
5269 js_object, name, value, attr, Object::OPTIMAL_REPRESENTATION, | 5263 js_object, name, value, attr, ALLOW_AS_CONSTANT, |
5270 ALLOW_AS_CONSTANT, JSReceiver::PERFORM_EXTENSIBILITY_CHECK, | 5264 JSReceiver::PERFORM_EXTENSIBILITY_CHECK, store_from_keyed); |
5271 store_from_keyed); | |
5272 } | 5265 } |
5273 } | 5266 } |
5274 | 5267 |
5275 | 5268 |
5276 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate, | 5269 MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate, |
5277 Handle<JSReceiver> receiver, | 5270 Handle<JSReceiver> receiver, |
5278 Handle<Object> key, | 5271 Handle<Object> key, |
5279 JSReceiver::DeleteMode mode) { | 5272 JSReceiver::DeleteMode mode) { |
5280 // Check if the given key is an array index. | 5273 // Check if the given key is an array index. |
5281 uint32_t index; | 5274 uint32_t index; |
(...skipping 7811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13093 // Check parameters. | 13086 // Check parameters. |
13094 CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0); | 13087 CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0); |
13095 CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1); | 13088 CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1); |
13096 RUNTIME_ASSERT(instance_filter->IsUndefined() || | 13089 RUNTIME_ASSERT(instance_filter->IsUndefined() || |
13097 instance_filter->IsJSObject()); | 13090 instance_filter->IsJSObject()); |
13098 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); | 13091 CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); |
13099 RUNTIME_ASSERT(max_references >= 0); | 13092 RUNTIME_ASSERT(max_references >= 0); |
13100 | 13093 |
13101 | 13094 |
13102 // Get the constructor function for context extension and arguments array. | 13095 // Get the constructor function for context extension and arguments array. |
13103 Handle<JSObject> arguments_boilerplate( | |
13104 isolate->sloppy_arguments_boilerplate()); | |
13105 Handle<JSFunction> arguments_function( | 13096 Handle<JSFunction> arguments_function( |
13106 JSFunction::cast(arguments_boilerplate->map()->constructor())); | 13097 JSFunction::cast(isolate->sloppy_arguments_map()->constructor())); |
13107 | 13098 |
13108 // Get the number of referencing objects. | 13099 // Get the number of referencing objects. |
13109 int count; | 13100 int count; |
13110 // First perform a full GC in order to avoid dead objects and to make the heap | 13101 // First perform a full GC in order to avoid dead objects and to make the heap |
13111 // iterable. | 13102 // iterable. |
13112 Heap* heap = isolate->heap(); | 13103 Heap* heap = isolate->heap(); |
13113 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy"); | 13104 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy"); |
13114 { | 13105 { |
13115 HeapIterator heap_iterator(heap); | 13106 HeapIterator heap_iterator(heap); |
13116 count = DebugReferencedBy(&heap_iterator, | 13107 count = DebugReferencedBy(&heap_iterator, |
(...skipping 2000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15117 } | 15108 } |
15118 return NULL; | 15109 return NULL; |
15119 } | 15110 } |
15120 | 15111 |
15121 | 15112 |
15122 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15113 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15123 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15114 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15124 } | 15115 } |
15125 | 15116 |
15126 } } // namespace v8::internal | 15117 } } // namespace v8::internal |
OLD | NEW |