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