Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: src/runtime.cc

Issue 4078: - Added a map cache for literal objects. This will... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/objects.cc ('K') | « src/parser.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« src/objects.cc ('K') | « src/parser.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698