OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2462 Object* obj; | 2462 Object* obj; |
2463 | 2463 |
2464 { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); | 2464 { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); |
2465 if (!maybe_obj->ToObject(&obj)) return false; | 2465 if (!maybe_obj->ToObject(&obj)) return false; |
2466 } | 2466 } |
2467 // Don't use Smi-only elements optimizations for objects with the neander | 2467 // Don't use Smi-only elements optimizations for objects with the neander |
2468 // map. There are too many cases where element values are set directly with a | 2468 // map. There are too many cases where element values are set directly with a |
2469 // bottleneck to trap the Smi-only -> fast elements transition, and there | 2469 // bottleneck to trap the Smi-only -> fast elements transition, and there |
2470 // appears to be no benefit for optimize this case. | 2470 // appears to be no benefit for optimize this case. |
2471 Map* new_neander_map = Map::cast(obj); | 2471 Map* new_neander_map = Map::cast(obj); |
2472 new_neander_map->set_elements_kind(FAST_ELEMENTS); | 2472 new_neander_map->set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND); |
2473 set_neander_map(new_neander_map); | 2473 set_neander_map(new_neander_map); |
2474 | 2474 |
2475 { MaybeObject* maybe_obj = AllocateJSObjectFromMap(neander_map()); | 2475 { MaybeObject* maybe_obj = AllocateJSObjectFromMap(neander_map()); |
2476 if (!maybe_obj->ToObject(&obj)) return false; | 2476 if (!maybe_obj->ToObject(&obj)) return false; |
2477 } | 2477 } |
2478 Object* elements; | 2478 Object* elements; |
2479 { MaybeObject* maybe_elements = AllocateFixedArray(2); | 2479 { MaybeObject* maybe_elements = AllocateFixedArray(2); |
2480 if (!maybe_elements->ToObject(&elements)) return false; | 2480 if (!maybe_elements->ToObject(&elements)) return false; |
2481 } | 2481 } |
2482 FixedArray::cast(elements)->set(0, Smi::FromInt(0)); | 2482 FixedArray::cast(elements)->set(0, Smi::FromInt(0)); |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3043 int end_position, | 3043 int end_position, |
3044 Object* script, | 3044 Object* script, |
3045 Object* stack_trace, | 3045 Object* stack_trace, |
3046 Object* stack_frames) { | 3046 Object* stack_frames) { |
3047 Object* result; | 3047 Object* result; |
3048 { MaybeObject* maybe_result = Allocate(message_object_map(), NEW_SPACE); | 3048 { MaybeObject* maybe_result = Allocate(message_object_map(), NEW_SPACE); |
3049 if (!maybe_result->ToObject(&result)) return maybe_result; | 3049 if (!maybe_result->ToObject(&result)) return maybe_result; |
3050 } | 3050 } |
3051 JSMessageObject* message = JSMessageObject::cast(result); | 3051 JSMessageObject* message = JSMessageObject::cast(result); |
3052 message->set_properties(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER); | 3052 message->set_properties(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER); |
| 3053 message->initialize_elements(); |
3053 message->set_elements(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER); | 3054 message->set_elements(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER); |
3054 message->set_type(type); | 3055 message->set_type(type); |
3055 message->set_arguments(arguments); | 3056 message->set_arguments(arguments); |
3056 message->set_start_position(start_position); | 3057 message->set_start_position(start_position); |
3057 message->set_end_position(end_position); | 3058 message->set_end_position(end_position); |
3058 message->set_script(script); | 3059 message->set_script(script); |
3059 message->set_stack_trace(stack_trace); | 3060 message->set_stack_trace(stack_trace); |
3060 message->set_stack_frames(stack_frames); | 3061 message->set_stack_frames(stack_frames); |
3061 return result; | 3062 return result; |
3062 } | 3063 } |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3744 Smi::FromInt(length), | 3745 Smi::FromInt(length), |
3745 SKIP_WRITE_BARRIER); | 3746 SKIP_WRITE_BARRIER); |
3746 // Set the callee property for non-strict mode arguments object only. | 3747 // Set the callee property for non-strict mode arguments object only. |
3747 if (!strict_mode_callee) { | 3748 if (!strict_mode_callee) { |
3748 JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex, | 3749 JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex, |
3749 callee); | 3750 callee); |
3750 } | 3751 } |
3751 | 3752 |
3752 // Check the state of the object | 3753 // Check the state of the object |
3753 ASSERT(JSObject::cast(result)->HasFastProperties()); | 3754 ASSERT(JSObject::cast(result)->HasFastProperties()); |
3754 ASSERT(JSObject::cast(result)->HasFastElements()); | 3755 ASSERT(JSObject::cast(result)->HasFastObjectElements()); |
3755 | 3756 |
3756 return result; | 3757 return result; |
3757 } | 3758 } |
3758 | 3759 |
3759 | 3760 |
3760 static bool HasDuplicates(DescriptorArray* descriptors) { | 3761 static bool HasDuplicates(DescriptorArray* descriptors) { |
3761 int count = descriptors->number_of_descriptors(); | 3762 int count = descriptors->number_of_descriptors(); |
3762 if (count > 1) { | 3763 if (count > 1) { |
3763 String* prev_key = descriptors->GetKey(0); | 3764 String* prev_key = descriptors->GetKey(0); |
3764 for (int i = 1; i != count; i++) { | 3765 for (int i = 1; i != count; i++) { |
(...skipping 24 matching lines...) Expand all Loading... |
3789 prototype = fun->instance_prototype(); | 3790 prototype = fun->instance_prototype(); |
3790 } else { | 3791 } else { |
3791 { MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun); | 3792 { MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun); |
3792 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; | 3793 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; |
3793 } | 3794 } |
3794 } | 3795 } |
3795 Map* map = Map::cast(map_obj); | 3796 Map* map = Map::cast(map_obj); |
3796 map->set_inobject_properties(in_object_properties); | 3797 map->set_inobject_properties(in_object_properties); |
3797 map->set_unused_property_fields(in_object_properties); | 3798 map->set_unused_property_fields(in_object_properties); |
3798 map->set_prototype(prototype); | 3799 map->set_prototype(prototype); |
3799 ASSERT(map->has_fast_elements()); | 3800 ASSERT(map->has_fast_object_elements()); |
3800 | 3801 |
3801 // If the function has only simple this property assignments add | 3802 // If the function has only simple this property assignments add |
3802 // field descriptors for these to the initial map as the object | 3803 // field descriptors for these to the initial map as the object |
3803 // cannot be constructed without having these properties. Guard by | 3804 // cannot be constructed without having these properties. Guard by |
3804 // the inline_new flag so we only change the map if we generate a | 3805 // the inline_new flag so we only change the map if we generate a |
3805 // specialized construct stub. | 3806 // specialized construct stub. |
3806 ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields); | 3807 ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields); |
3807 if (fun->shared()->CanGenerateInlineConstructor(prototype)) { | 3808 if (fun->shared()->CanGenerateInlineConstructor(prototype)) { |
3808 int count = fun->shared()->this_property_assignments_count(); | 3809 int count = fun->shared()->this_property_assignments_count(); |
3809 if (count > in_object_properties) { | 3810 if (count > in_object_properties) { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3906 if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE; | 3907 if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE; |
3907 Object* obj; | 3908 Object* obj; |
3908 { MaybeObject* maybe_obj = Allocate(map, space); | 3909 { MaybeObject* maybe_obj = Allocate(map, space); |
3909 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3910 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
3910 } | 3911 } |
3911 | 3912 |
3912 // Initialize the JSObject. | 3913 // Initialize the JSObject. |
3913 InitializeJSObjectFromMap(JSObject::cast(obj), | 3914 InitializeJSObjectFromMap(JSObject::cast(obj), |
3914 FixedArray::cast(properties), | 3915 FixedArray::cast(properties), |
3915 map); | 3916 map); |
3916 ASSERT(JSObject::cast(obj)->HasFastSmiOnlyElements() || | 3917 ASSERT(JSObject::cast(obj)->HasFastSmiOrObjectElements()); |
3917 JSObject::cast(obj)->HasFastElements()); | |
3918 return obj; | 3918 return obj; |
3919 } | 3919 } |
3920 | 3920 |
3921 | 3921 |
3922 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, | 3922 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, |
3923 PretenureFlag pretenure) { | 3923 PretenureFlag pretenure) { |
3924 // Allocate the initial map if absent. | 3924 // Allocate the initial map if absent. |
3925 if (!constructor->has_initial_map()) { | 3925 if (!constructor->has_initial_map()) { |
3926 Object* initial_map; | 3926 Object* initial_map; |
3927 { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor); | 3927 { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor); |
(...skipping 24 matching lines...) Expand all Loading... |
3952 } | 3952 } |
3953 | 3953 |
3954 | 3954 |
3955 MaybeObject* Heap::AllocateJSArrayAndStorage( | 3955 MaybeObject* Heap::AllocateJSArrayAndStorage( |
3956 ElementsKind elements_kind, | 3956 ElementsKind elements_kind, |
3957 int length, | 3957 int length, |
3958 int capacity, | 3958 int capacity, |
3959 ArrayStorageAllocationMode mode, | 3959 ArrayStorageAllocationMode mode, |
3960 PretenureFlag pretenure) { | 3960 PretenureFlag pretenure) { |
3961 ASSERT(capacity >= length); | 3961 ASSERT(capacity >= length); |
| 3962 if (length != 0 && mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE) { |
| 3963 elements_kind = GetHoleyElementsKind(elements_kind); |
| 3964 } |
3962 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure); | 3965 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure); |
3963 JSArray* array; | 3966 JSArray* array; |
3964 if (!maybe_array->To(&array)) return maybe_array; | 3967 if (!maybe_array->To(&array)) return maybe_array; |
3965 | 3968 |
3966 if (capacity == 0) { | 3969 if (capacity == 0) { |
3967 array->set_length(Smi::FromInt(0)); | 3970 array->set_length(Smi::FromInt(0)); |
3968 array->set_elements(empty_fixed_array()); | 3971 array->set_elements(empty_fixed_array()); |
3969 return array; | 3972 return array; |
3970 } | 3973 } |
3971 | 3974 |
3972 FixedArrayBase* elms; | 3975 FixedArrayBase* elms; |
3973 MaybeObject* maybe_elms = NULL; | 3976 MaybeObject* maybe_elms = NULL; |
3974 if (elements_kind == FAST_DOUBLE_ELEMENTS) { | 3977 if (elements_kind == FAST_DOUBLE_ELEMENTS) { |
3975 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { | 3978 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { |
3976 maybe_elms = AllocateUninitializedFixedDoubleArray(capacity); | 3979 maybe_elms = AllocateUninitializedFixedDoubleArray(capacity); |
3977 } else { | 3980 } else { |
3978 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); | 3981 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); |
3979 maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity); | 3982 maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity); |
3980 } | 3983 } |
3981 } else { | 3984 } else { |
3982 ASSERT(elements_kind == FAST_ELEMENTS || | 3985 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind)); |
3983 elements_kind == FAST_SMI_ONLY_ELEMENTS); | |
3984 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { | 3986 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { |
3985 maybe_elms = AllocateUninitializedFixedArray(capacity); | 3987 maybe_elms = AllocateUninitializedFixedArray(capacity); |
3986 } else { | 3988 } else { |
3987 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); | 3989 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); |
3988 maybe_elms = AllocateFixedArrayWithHoles(capacity); | 3990 maybe_elms = AllocateFixedArrayWithHoles(capacity); |
3989 } | 3991 } |
3990 } | 3992 } |
3991 if (!maybe_elms->To(&elms)) return maybe_elms; | 3993 if (!maybe_elms->To(&elms)) return maybe_elms; |
3992 | 3994 |
3993 array->set_elements(elms); | 3995 array->set_elements(elms); |
3994 array->set_length(Smi::FromInt(length)); | 3996 array->set_length(Smi::FromInt(length)); |
3995 return array; | 3997 return array; |
3996 } | 3998 } |
3997 | 3999 |
3998 | 4000 |
3999 MaybeObject* Heap::AllocateJSArrayWithElements( | 4001 MaybeObject* Heap::AllocateJSArrayWithElements( |
4000 FixedArrayBase* elements, | 4002 FixedArrayBase* elements, |
4001 ElementsKind elements_kind, | 4003 ElementsKind elements_kind, |
4002 PretenureFlag pretenure) { | 4004 PretenureFlag pretenure) { |
4003 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure); | 4005 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure); |
4004 JSArray* array; | 4006 JSArray* array; |
4005 if (!maybe_array->To(&array)) return maybe_array; | 4007 if (!maybe_array->To(&array)) return maybe_array; |
4006 | 4008 |
4007 array->set_elements(elements); | 4009 array->set_elements(elements); |
4008 array->set_length(Smi::FromInt(elements->length())); | 4010 array->set_length(Smi::FromInt(elements->length())); |
| 4011 array->ValidateElements(); |
4009 return array; | 4012 return array; |
4010 } | 4013 } |
4011 | 4014 |
4012 | 4015 |
4013 MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) { | 4016 MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) { |
4014 // Allocate map. | 4017 // Allocate map. |
4015 // TODO(rossberg): Once we optimize proxies, think about a scheme to share | 4018 // TODO(rossberg): Once we optimize proxies, think about a scheme to share |
4016 // maps. Will probably depend on the identity of the handler object, too. | 4019 // maps. Will probably depend on the identity of the handler object, too. |
4017 Map* map; | 4020 Map* map; |
4018 MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize); | 4021 MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize); |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4529 return result; | 4532 return result; |
4530 } | 4533 } |
4531 | 4534 |
4532 | 4535 |
4533 MaybeObject* Heap::AllocateJSArray( | 4536 MaybeObject* Heap::AllocateJSArray( |
4534 ElementsKind elements_kind, | 4537 ElementsKind elements_kind, |
4535 PretenureFlag pretenure) { | 4538 PretenureFlag pretenure) { |
4536 Context* global_context = isolate()->context()->global_context(); | 4539 Context* global_context = isolate()->context()->global_context(); |
4537 JSFunction* array_function = global_context->array_function(); | 4540 JSFunction* array_function = global_context->array_function(); |
4538 Map* map = array_function->initial_map(); | 4541 Map* map = array_function->initial_map(); |
4539 if (elements_kind == FAST_DOUBLE_ELEMENTS) { | 4542 Object* maybe_map_array = global_context->js_array_maps(); |
4540 map = Map::cast(global_context->double_js_array_map()); | 4543 if (!maybe_map_array->IsUndefined()) { |
4541 } else if (elements_kind == FAST_ELEMENTS || !FLAG_smi_only_arrays) { | 4544 Object* maybe_transitioned_map = |
4542 map = Map::cast(global_context->object_js_array_map()); | 4545 FixedArray::cast(maybe_map_array)->get(elements_kind); |
4543 } else { | 4546 if (!maybe_transitioned_map->IsUndefined()) { |
4544 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS); | 4547 map = Map::cast(maybe_transitioned_map); |
4545 ASSERT(map == global_context->smi_js_array_map()); | 4548 } |
4546 } | 4549 } |
4547 | 4550 |
4548 return AllocateJSObjectFromMap(map, pretenure); | 4551 return AllocateJSObjectFromMap(map, pretenure); |
4549 } | 4552 } |
4550 | 4553 |
4551 | 4554 |
4552 MaybeObject* Heap::AllocateEmptyFixedArray() { | 4555 MaybeObject* Heap::AllocateEmptyFixedArray() { |
4553 int size = FixedArray::SizeFor(0); | 4556 int size = FixedArray::SizeFor(0); |
4554 Object* result; | 4557 Object* result; |
4555 { MaybeObject* maybe_result = | 4558 { MaybeObject* maybe_result = |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4820 | 4823 |
4821 | 4824 |
4822 MaybeObject* Heap::AllocateGlobalContext() { | 4825 MaybeObject* Heap::AllocateGlobalContext() { |
4823 Object* result; | 4826 Object* result; |
4824 { MaybeObject* maybe_result = | 4827 { MaybeObject* maybe_result = |
4825 AllocateFixedArray(Context::GLOBAL_CONTEXT_SLOTS); | 4828 AllocateFixedArray(Context::GLOBAL_CONTEXT_SLOTS); |
4826 if (!maybe_result->ToObject(&result)) return maybe_result; | 4829 if (!maybe_result->ToObject(&result)) return maybe_result; |
4827 } | 4830 } |
4828 Context* context = reinterpret_cast<Context*>(result); | 4831 Context* context = reinterpret_cast<Context*>(result); |
4829 context->set_map_no_write_barrier(global_context_map()); | 4832 context->set_map_no_write_barrier(global_context_map()); |
4830 context->set_smi_js_array_map(undefined_value()); | 4833 context->set_js_array_maps(undefined_value()); |
4831 context->set_double_js_array_map(undefined_value()); | |
4832 context->set_object_js_array_map(undefined_value()); | |
4833 ASSERT(context->IsGlobalContext()); | 4834 ASSERT(context->IsGlobalContext()); |
4834 ASSERT(result->IsContext()); | 4835 ASSERT(result->IsContext()); |
4835 return result; | 4836 return result; |
4836 } | 4837 } |
4837 | 4838 |
4838 | 4839 |
4839 MaybeObject* Heap::AllocateModuleContext(Context* previous, | 4840 MaybeObject* Heap::AllocateModuleContext(Context* previous, |
4840 ScopeInfo* scope_info) { | 4841 ScopeInfo* scope_info) { |
4841 Object* result; | 4842 Object* result; |
4842 { MaybeObject* maybe_result = | 4843 { MaybeObject* maybe_result = |
(...skipping 2289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7132 } else { | 7133 } else { |
7133 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. | 7134 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. |
7134 } | 7135 } |
7135 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = | 7136 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = |
7136 reinterpret_cast<Address>(p); | 7137 reinterpret_cast<Address>(p); |
7137 remembered_unmapped_pages_index_++; | 7138 remembered_unmapped_pages_index_++; |
7138 remembered_unmapped_pages_index_ %= kRememberedUnmappedPages; | 7139 remembered_unmapped_pages_index_ %= kRememberedUnmappedPages; |
7139 } | 7140 } |
7140 | 7141 |
7141 } } // namespace v8::internal | 7142 } } // namespace v8::internal |
OLD | NEW |