OLD | NEW |
---|---|
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
90 return Top::Throw(Heap::illegal_access_symbol()); | 90 return Top::Throw(Heap::illegal_access_symbol()); |
91 } | 91 } |
92 | 92 |
93 | 93 |
94 static Object* Runtime_CloneObjectLiteralBoilerplate(Arguments args) { | 94 static Object* Runtime_CloneObjectLiteralBoilerplate(Arguments args) { |
95 CONVERT_CHECKED(JSObject, boilerplate, args[0]); | 95 CONVERT_CHECKED(JSObject, boilerplate, args[0]); |
96 return boilerplate->Copy(); | 96 return boilerplate->Copy(); |
97 } | 97 } |
98 | 98 |
99 | 99 |
100 static Handle<Map> ComputeObjectLiteralMap(Handle<Context> context, | |
101 Handle<FixedArray> constant_properties, | |
Mads Ager (chromium)
2008/09/25 07:23:19
Indentation slightly off here.
| |
102 bool &is_result_from_cache) { | |
103 if (FLAG_canonicalize_object_literal_maps) { | |
104 // First find prefix of consecutive symbol keys. | |
105 int number_of_properties = constant_properties->length()/2; | |
106 int number_of_symbol_keys = 0; | |
107 while ((number_of_symbol_keys < number_of_properties) | |
Mads Ager (chromium)
2008/09/25 07:23:19
How about:
while ((number_of_symbol_keys ==
| |
108 && (constant_properties->get(number_of_symbol_keys*2) | |
109 ->IsSymbol())) { | |
110 number_of_symbol_keys++; | |
111 } | |
112 // Based on the number of prefix symbols key we decide whether | |
113 // to use the map cache in the global context. | |
114 const int kMaxKeys = 10; | |
115 if ((number_of_symbol_keys == number_of_properties) | |
116 && (number_of_symbol_keys < kMaxKeys)) { | |
117 // Create the fixed array with the key. | |
Mads Ager (chromium)
2008/09/25 07:23:19
Indent two more spaces?
| |
118 Handle<FixedArray> keys = Factory::NewFixedArray(number_of_symbol_keys); | |
119 for (int i = 0; i < number_of_symbol_keys; i++) { | |
120 keys->set(i, constant_properties->get(i*2)); | |
121 } | |
122 is_result_from_cache = true; | |
123 return Factory::ObjectLiteralMapFromCache(context, keys); | |
124 } | |
125 } | |
126 is_result_from_cache = false; | |
127 return Handle<Map>(context->object_function()->initial_map()); | |
128 } | |
129 | |
130 | |
100 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) { | 131 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) { |
101 HandleScope scope; | 132 HandleScope scope; |
102 ASSERT(args.length() == 3); | 133 ASSERT(args.length() == 3); |
103 // Copy the arguments. | 134 // Copy the arguments. |
104 Handle<FixedArray> literals = args.at<FixedArray>(0); | 135 Handle<FixedArray> literals = args.at<FixedArray>(0); |
105 int literals_index = Smi::cast(args[1])->value(); | 136 int literals_index = Smi::cast(args[1])->value(); |
106 Handle<FixedArray> constant_properties = args.at<FixedArray>(2); | 137 Handle<FixedArray> constant_properties = args.at<FixedArray>(2); |
138 Handle<Context> context = | |
139 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); | |
140 | |
141 bool is_result_from_cache; | |
142 Handle<Map> map = ComputeObjectLiteralMap(context, | |
143 constant_properties, | |
144 is_result_from_cache); | |
107 | 145 |
108 // Get the object function from the literals array. This is the | 146 // Get the object function from the literals array. This is the |
109 // object function from the context in which the function was | 147 // object function from the context in which the function was |
110 // created. We do not use the object function from the current | 148 // created. We do not use the object function from the current |
111 // global context because this might be the object function from | 149 // global context because this might be the object function from |
112 // another context which we should not have access to. | 150 // another context which we should not have access to. |
113 const int kObjectFunIndex = JSFunction::kLiteralObjectFunctionIndex; | 151 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); |
114 Handle<JSFunction> constructor = | |
115 Handle<JSFunction>(JSFunction::cast(literals->get(kObjectFunIndex))); | |
116 | |
117 Handle<JSObject> boilerplate = Factory::NewJSObject(constructor, TENURED); | |
118 | |
119 { // Add the constant propeties to the boilerplate. | 152 { // Add the constant propeties to the boilerplate. |
120 int length = constant_properties->length(); | 153 int length = constant_properties->length(); |
121 OptimizedObjectForAddingMultipleProperties opt(boilerplate, true); | 154 OptimizedObjectForAddingMultipleProperties opt(boilerplate, |
155 !is_result_from_cache); | |
122 for (int index = 0; index < length; index +=2) { | 156 for (int index = 0; index < length; index +=2) { |
123 Handle<Object> key(constant_properties->get(index+0)); | 157 Handle<Object> key(constant_properties->get(index+0)); |
124 Handle<Object> value(constant_properties->get(index+1)); | 158 Handle<Object> value(constant_properties->get(index+1)); |
125 uint32_t element_index = 0; | 159 uint32_t element_index = 0; |
126 if (key->IsSymbol()) { | 160 if (key->IsSymbol()) { |
127 // If key is a symbol it is not an array element. | 161 // If key is a symbol it is not an array element. |
128 Handle<String> name(String::cast(*key)); | 162 Handle<String> name(String::cast(*key)); |
129 ASSERT(!name->AsArrayIndex(&element_index)); | 163 ASSERT(!name->AsArrayIndex(&element_index)); |
130 SetProperty(boilerplate, name, value, NONE); | 164 SetProperty(boilerplate, name, value, NONE); |
131 } else if (Array::IndexFromObject(*key, &element_index)) { | 165 } else if (Array::IndexFromObject(*key, &element_index)) { |
(...skipping 21 matching lines...) Expand all Loading... | |
153 | 187 |
154 static Object* Runtime_CreateArrayLiteral(Arguments args) { | 188 static Object* Runtime_CreateArrayLiteral(Arguments args) { |
155 // Takes a FixedArray of elements containing the literal elements of | 189 // Takes a FixedArray of elements containing the literal elements of |
156 // the array literal and produces JSArray with those elements. | 190 // the array literal and produces JSArray with those elements. |
157 // Additionally takes the literals array of the surrounding function | 191 // Additionally takes the literals array of the surrounding function |
158 // which contains the Array function to use for creating the array | 192 // which contains the Array function to use for creating the array |
159 // literal. | 193 // literal. |
160 ASSERT(args.length() == 2); | 194 ASSERT(args.length() == 2); |
161 CONVERT_CHECKED(FixedArray, elements, args[0]); | 195 CONVERT_CHECKED(FixedArray, elements, args[0]); |
162 CONVERT_CHECKED(FixedArray, literals, args[1]); | 196 CONVERT_CHECKED(FixedArray, literals, args[1]); |
163 const int kArrayFunIndex = JSFunction::kLiteralArrayFunctionIndex; | 197 JSFunction* constructor = |
164 JSFunction* constructor = JSFunction::cast(literals->get(kArrayFunIndex)); | 198 JSFunction::GlobalContextFromLiterals(literals)->array_function(); |
165 | |
166 // Create the JSArray. | 199 // Create the JSArray. |
167 Object* object = Heap::AllocateJSObject(constructor); | 200 Object* object = Heap::AllocateJSObject(constructor); |
168 if (object->IsFailure()) return object; | 201 if (object->IsFailure()) return object; |
169 | 202 |
170 // Copy the elements. | 203 // Copy the elements. |
171 Object* content = elements->Copy(); | 204 Object* content = elements->Copy(); |
172 if (content->IsFailure()) return content; | 205 if (content->IsFailure()) return content; |
173 | 206 |
174 // Set the elements. | 207 // Set the elements. |
175 JSArray::cast(object)->SetContent(FixedArray::cast(content)); | 208 JSArray::cast(object)->SetContent(FixedArray::cast(content)); |
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
692 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 725 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
693 int index = Smi::cast(args[1])->value(); | 726 int index = Smi::cast(args[1])->value(); |
694 Handle<String> pattern = args.at<String>(2); | 727 Handle<String> pattern = args.at<String>(2); |
695 Handle<String> flags = args.at<String>(3); | 728 Handle<String> flags = args.at<String>(3); |
696 | 729 |
697 // Get the RegExp function from the literals array. This is the | 730 // Get the RegExp function from the literals array. This is the |
698 // RegExp function from the context in which the function was | 731 // RegExp function from the context in which the function was |
699 // created. We do not use the RegExp function from the current | 732 // created. We do not use the RegExp function from the current |
700 // global context because this might be the RegExp function from | 733 // global context because this might be the RegExp function from |
701 // another context which we should not have access to. | 734 // another context which we should not have access to. |
702 const int kRegexpFunIndex = JSFunction::kLiteralRegExpFunctionIndex; | |
703 Handle<JSFunction> constructor = | 735 Handle<JSFunction> constructor = |
704 Handle<JSFunction>(JSFunction::cast(literals->get(kRegexpFunIndex))); | 736 Handle<JSFunction>( |
705 | 737 JSFunction::GlobalContextFromLiterals(*literals)->regexp_function()); |
706 // Compute the regular expression literal. | 738 // Compute the regular expression literal. |
707 bool has_pending_exception; | 739 bool has_pending_exception; |
708 Handle<Object> regexp = | 740 Handle<Object> regexp = |
709 RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags, | 741 RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags, |
710 &has_pending_exception); | 742 &has_pending_exception); |
711 if (has_pending_exception) { | 743 if (has_pending_exception) { |
712 ASSERT(Top::has_pending_exception()); | 744 ASSERT(Top::has_pending_exception()); |
713 return Failure::Exception(); | 745 return Failure::Exception(); |
714 } | 746 } |
715 literals->set(index, *regexp); | 747 literals->set(index, *regexp); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
821 | 853 |
822 // Make sure we get a fresh copy of the literal vector to avoid | 854 // Make sure we get a fresh copy of the literal vector to avoid |
823 // cross context contamination. | 855 // cross context contamination. |
824 int number_of_literals = fun->NumberOfLiterals(); | 856 int number_of_literals = fun->NumberOfLiterals(); |
825 Handle<FixedArray> literals = | 857 Handle<FixedArray> literals = |
826 Factory::NewFixedArray(number_of_literals, TENURED); | 858 Factory::NewFixedArray(number_of_literals, TENURED); |
827 if (number_of_literals > 0) { | 859 if (number_of_literals > 0) { |
828 // Insert the object, regexp and array functions in the literals | 860 // Insert the object, regexp and array functions in the literals |
829 // array prefix. These are the functions that will be used when | 861 // array prefix. These are the functions that will be used when |
830 // creating object, regexp and array literals. | 862 // creating object, regexp and array literals. |
831 literals->set(JSFunction::kLiteralObjectFunctionIndex, | 863 literals->set(JSFunction::kLiteralGlobalContextIndex, |
832 context->global_context()->object_function()); | 864 context->global_context()); |
833 literals->set(JSFunction::kLiteralRegExpFunctionIndex, | |
834 context->global_context()->regexp_function()); | |
835 literals->set(JSFunction::kLiteralArrayFunctionIndex, | |
836 context->global_context()->array_function()); | |
837 } | 865 } |
838 target->set_literals(*literals); | 866 target->set_literals(*literals); |
839 } | 867 } |
840 | 868 |
841 target->set_context(*context); | 869 target->set_context(*context); |
842 return *target; | 870 return *target; |
843 } | 871 } |
844 | 872 |
845 | 873 |
846 static Object* CharCodeAt(String* subject, Object* index) { | 874 static Object* CharCodeAt(String* subject, Object* index) { |
(...skipping 4129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4976 | 5004 |
4977 void Runtime::PerformGC(Object* result) { | 5005 void Runtime::PerformGC(Object* result) { |
4978 Failure* failure = Failure::cast(result); | 5006 Failure* failure = Failure::cast(result); |
4979 // Try to do a garbage collection; ignore it if it fails. The C | 5007 // Try to do a garbage collection; ignore it if it fails. The C |
4980 // entry stub will throw an out-of-memory exception in that case. | 5008 // entry stub will throw an out-of-memory exception in that case. |
4981 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); | 5009 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); |
4982 } | 5010 } |
4983 | 5011 |
4984 | 5012 |
4985 } } // namespace v8::internal | 5013 } } // namespace v8::internal |
OLD | NEW |