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

Side by Side Diff: src/runtime.cc

Issue 335653002: Have one, long-lived map for bound functions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 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
OLDNEW
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 8173 matching lines...) Expand 10 before | Expand all | Expand 10 after
8184 } 8184 }
8185 return param_data; 8185 return param_data;
8186 } 8186 }
8187 } 8187 }
8188 8188
8189 8189
8190 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) { 8190 RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
8191 HandleScope scope(isolate); 8191 HandleScope scope(isolate);
8192 ASSERT(args.length() == 4); 8192 ASSERT(args.length() == 4);
8193 CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0); 8193 CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
8194 RUNTIME_ASSERT(args[3]->IsNumber()); 8194 CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1);
8195 Handle<Object> bindee = args.at<Object>(1); 8195 CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
8196 CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
8196 8197
8197 // TODO(lrn): Create bound function in C++ code from premade shared info. 8198 // TODO(lrn): Create bound function in C++ code from premade shared info.
8198 bound_function->shared()->set_bound(true); 8199 bound_function->shared()->set_bound(true);
8199 // Get all arguments of calling function (Function.prototype.bind). 8200 // Get all arguments of calling function (Function.prototype.bind).
8200 int argc = 0; 8201 int argc = 0;
8201 SmartArrayPointer<Handle<Object> > arguments = 8202 SmartArrayPointer<Handle<Object> > arguments =
8202 GetCallerArguments(isolate, 0, &argc); 8203 GetCallerArguments(isolate, 0, &argc);
8203 // Don't count the this-arg. 8204 // Don't count the this-arg.
8204 if (argc > 0) { 8205 if (argc > 0) {
8205 RUNTIME_ASSERT(*arguments[0] == args[2]); 8206 RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
8206 argc--; 8207 argc--;
8207 } else { 8208 } else {
8208 RUNTIME_ASSERT(args[2]->IsUndefined()); 8209 RUNTIME_ASSERT(this_object->IsUndefined());
8209 } 8210 }
8210 // Initialize array of bindings (function, this, and any existing arguments 8211 // Initialize array of bindings (function, this, and any existing arguments
8211 // if the function was already bound). 8212 // if the function was already bound).
8212 Handle<FixedArray> new_bindings; 8213 Handle<FixedArray> new_bindings;
8213 int i; 8214 int i;
8214 if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) { 8215 if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
8215 Handle<FixedArray> old_bindings( 8216 Handle<FixedArray> old_bindings(
8216 JSFunction::cast(*bindee)->function_bindings()); 8217 JSFunction::cast(*bindee)->function_bindings());
8217 RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex); 8218 RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
8218 new_bindings = 8219 new_bindings =
8219 isolate->factory()->NewFixedArray(old_bindings->length() + argc); 8220 isolate->factory()->NewFixedArray(old_bindings->length() + argc);
8220 bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex), 8221 bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
8221 isolate); 8222 isolate);
8222 i = 0; 8223 i = 0;
8223 for (int n = old_bindings->length(); i < n; i++) { 8224 for (int n = old_bindings->length(); i < n; i++) {
8224 new_bindings->set(i, old_bindings->get(i)); 8225 new_bindings->set(i, old_bindings->get(i));
8225 } 8226 }
8226 } else { 8227 } else {
8227 int array_size = JSFunction::kBoundArgumentsStartIndex + argc; 8228 int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
8228 new_bindings = isolate->factory()->NewFixedArray(array_size); 8229 new_bindings = isolate->factory()->NewFixedArray(array_size);
8229 new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee); 8230 new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
8230 new_bindings->set(JSFunction::kBoundThisIndex, args[2]); 8231 new_bindings->set(JSFunction::kBoundThisIndex, *this_object);
8231 i = 2; 8232 i = 2;
8232 } 8233 }
8233 // Copy arguments, skipping the first which is "this_arg". 8234 // Copy arguments, skipping the first which is "this_arg".
8234 for (int j = 0; j < argc; j++, i++) { 8235 for (int j = 0; j < argc; j++, i++) {
8235 new_bindings->set(i, *arguments[j + 1]); 8236 new_bindings->set(i, *arguments[j + 1]);
8236 } 8237 }
8237 new_bindings->set_map_no_write_barrier( 8238 new_bindings->set_map_no_write_barrier(
8238 isolate->heap()->fixed_cow_array_map()); 8239 isolate->heap()->fixed_cow_array_map());
8239 bound_function->set_function_bindings(*new_bindings); 8240 bound_function->set_function_bindings(*new_bindings);
8240 8241
8241 // Update length. 8242 // Update length. Have to remove the prototype first so that map migration
8243 // is happy about the number of fields.
8244 RUNTIME_ASSERT(bound_function->RemovePrototype());
8245 Handle<Map> bound_function_map(
8246 isolate->native_context()->bound_function_map());
8247 JSObject::MigrateToMap(bound_function, bound_function_map);
8242 Handle<String> length_string = isolate->factory()->length_string(); 8248 Handle<String> length_string = isolate->factory()->length_string();
8243 Handle<Object> new_length(args.at<Object>(3));
8244 PropertyAttributes attr = 8249 PropertyAttributes attr =
8245 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY); 8250 static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
8246 Runtime::ForceSetObjectProperty( 8251 JSObject::SetOwnPropertyIgnoreAttributes(bound_function, length_string,
8247 bound_function, length_string, new_length, attr).Assert(); 8252 new_length, attr);
8248 return *bound_function; 8253 return *bound_function;
8249 } 8254 }
8250 8255
8251 8256
8252 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) { 8257 RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
8253 HandleScope handles(isolate); 8258 HandleScope handles(isolate);
8254 ASSERT(args.length() == 1); 8259 ASSERT(args.length() == 1);
8255 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0); 8260 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
8256 if (callable->IsJSFunction()) { 8261 if (callable->IsJSFunction()) {
8257 Handle<JSFunction> function = Handle<JSFunction>::cast(callable); 8262 Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
(...skipping 6944 matching lines...) Expand 10 before | Expand all | Expand 10 after
15202 } 15207 }
15203 return NULL; 15208 return NULL;
15204 } 15209 }
15205 15210
15206 15211
15207 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 15212 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
15208 return &(kIntrinsicFunctions[static_cast<int>(id)]); 15213 return &(kIntrinsicFunctions[static_cast<int>(id)]);
15209 } 15214 }
15210 15215
15211 } } // namespace v8::internal 15216 } } // namespace v8::internal
OLDNEW
« src/bootstrapper.cc ('K') | « src/contexts.h ('k') | src/v8natives.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698