Index: src/runtime.cc |
=================================================================== |
--- src/runtime.cc (revision 369) |
+++ src/runtime.cc (working copy) |
@@ -97,6 +97,37 @@ |
} |
+static Handle<Map> ComputeObjectLiteralMap(Handle<Context> context, |
+ Handle<FixedArray> constant_properties, |
Mads Ager (chromium)
2008/09/25 07:23:19
Indentation slightly off here.
|
+ bool &is_result_from_cache) { |
+ if (FLAG_canonicalize_object_literal_maps) { |
+ // First find prefix of consecutive symbol keys. |
+ int number_of_properties = constant_properties->length()/2; |
+ int number_of_symbol_keys = 0; |
+ while ((number_of_symbol_keys < number_of_properties) |
Mads Ager (chromium)
2008/09/25 07:23:19
How about:
while ((number_of_symbol_keys ==
|
+ && (constant_properties->get(number_of_symbol_keys*2) |
+ ->IsSymbol())) { |
+ number_of_symbol_keys++; |
+ } |
+ // Based on the number of prefix symbols key we decide whether |
+ // to use the map cache in the global context. |
+ const int kMaxKeys = 10; |
+ if ((number_of_symbol_keys == number_of_properties) |
+ && (number_of_symbol_keys < kMaxKeys)) { |
+ // Create the fixed array with the key. |
Mads Ager (chromium)
2008/09/25 07:23:19
Indent two more spaces?
|
+ Handle<FixedArray> keys = Factory::NewFixedArray(number_of_symbol_keys); |
+ for (int i = 0; i < number_of_symbol_keys; i++) { |
+ keys->set(i, constant_properties->get(i*2)); |
+ } |
+ is_result_from_cache = true; |
+ return Factory::ObjectLiteralMapFromCache(context, keys); |
+ } |
+ } |
+ is_result_from_cache = false; |
+ return Handle<Map>(context->object_function()->initial_map()); |
+} |
+ |
+ |
static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) { |
HandleScope scope; |
ASSERT(args.length() == 3); |
@@ -104,21 +135,24 @@ |
Handle<FixedArray> literals = args.at<FixedArray>(0); |
int literals_index = Smi::cast(args[1])->value(); |
Handle<FixedArray> constant_properties = args.at<FixedArray>(2); |
+ Handle<Context> context = |
+ Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); |
+ bool is_result_from_cache; |
+ Handle<Map> map = ComputeObjectLiteralMap(context, |
+ constant_properties, |
+ is_result_from_cache); |
+ |
// Get the object function from the literals array. This is the |
// object function from the context in which the function was |
// created. We do not use the object function from the current |
// global context because this might be the object function from |
// another context which we should not have access to. |
- const int kObjectFunIndex = JSFunction::kLiteralObjectFunctionIndex; |
- Handle<JSFunction> constructor = |
- Handle<JSFunction>(JSFunction::cast(literals->get(kObjectFunIndex))); |
- |
- Handle<JSObject> boilerplate = Factory::NewJSObject(constructor, TENURED); |
- |
+ Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); |
{ // Add the constant propeties to the boilerplate. |
int length = constant_properties->length(); |
- OptimizedObjectForAddingMultipleProperties opt(boilerplate, true); |
+ OptimizedObjectForAddingMultipleProperties opt(boilerplate, |
+ !is_result_from_cache); |
for (int index = 0; index < length; index +=2) { |
Handle<Object> key(constant_properties->get(index+0)); |
Handle<Object> value(constant_properties->get(index+1)); |
@@ -160,9 +194,8 @@ |
ASSERT(args.length() == 2); |
CONVERT_CHECKED(FixedArray, elements, args[0]); |
CONVERT_CHECKED(FixedArray, literals, args[1]); |
- const int kArrayFunIndex = JSFunction::kLiteralArrayFunctionIndex; |
- JSFunction* constructor = JSFunction::cast(literals->get(kArrayFunIndex)); |
- |
+ JSFunction* constructor = |
+ JSFunction::GlobalContextFromLiterals(literals)->array_function(); |
// Create the JSArray. |
Object* object = Heap::AllocateJSObject(constructor); |
if (object->IsFailure()) return object; |
@@ -699,10 +732,9 @@ |
// created. We do not use the RegExp function from the current |
// global context because this might be the RegExp function from |
// another context which we should not have access to. |
- const int kRegexpFunIndex = JSFunction::kLiteralRegExpFunctionIndex; |
Handle<JSFunction> constructor = |
- Handle<JSFunction>(JSFunction::cast(literals->get(kRegexpFunIndex))); |
- |
+ Handle<JSFunction>( |
+ JSFunction::GlobalContextFromLiterals(*literals)->regexp_function()); |
// Compute the regular expression literal. |
bool has_pending_exception; |
Handle<Object> regexp = |
@@ -828,12 +860,8 @@ |
// Insert the object, regexp and array functions in the literals |
// array prefix. These are the functions that will be used when |
// creating object, regexp and array literals. |
- literals->set(JSFunction::kLiteralObjectFunctionIndex, |
- context->global_context()->object_function()); |
- literals->set(JSFunction::kLiteralRegExpFunctionIndex, |
- context->global_context()->regexp_function()); |
- literals->set(JSFunction::kLiteralArrayFunctionIndex, |
- context->global_context()->array_function()); |
+ literals->set(JSFunction::kLiteralGlobalContextIndex, |
+ context->global_context()); |
} |
target->set_literals(*literals); |
} |