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