Version 3.4.5
Fixed issues 794, 1097, 1215(partial), 1417, 1435, 1472, 1473, 1476, and 1477.
Improved code generation for !0 and !1.
Reduced memory usage for regular expressions with nested qualifiers. (issue 1472)
Fixed V8 to count line terminators in multi-line comments. (Chromium issue 86431)
Fixed disassembler=on option for release-mode builds. (issue 1473)
Performance improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@8337 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/runtime.cc b/src/runtime.cc
index a50303b..07f18ee 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -876,7 +876,13 @@
ASSERT(proto->IsJSGlobalObject());
holder = Handle<JSObject>(JSObject::cast(proto));
}
- NumberDictionary* dictionary = holder->element_dictionary();
+ FixedArray* elements = FixedArray::cast(holder->elements());
+ NumberDictionary* dictionary = NULL;
+ if (elements->map() == heap->non_strict_arguments_elements_map()) {
+ dictionary = NumberDictionary::cast(elements->get(1));
+ } else {
+ dictionary = NumberDictionary::cast(elements);
+ }
int entry = dictionary->FindEntry(index);
ASSERT(entry != NumberDictionary::kNotFound);
PropertyDetails details = dictionary->DetailsAt(entry);
@@ -1855,6 +1861,15 @@
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetBound) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+
+ CONVERT_CHECKED(JSFunction, fun, args[0]);
+ fun->shared()->set_bound(true);
+ return isolate->heap()->undefined_value();
+}
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionRemovePrototype) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
@@ -3896,7 +3911,7 @@
}
LookupResult result;
- js_object->LookupRealNamedProperty(*name, &result);
+ js_object->LocalLookupRealNamedProperty(*name, &result);
// To be compatible with safari we do not change the value on API objects
// in defineProperty. Firefox disagrees here, and actually changes the value.
@@ -4030,7 +4045,7 @@
Handle<String> name = Handle<String>::cast(converted);
if (name->AsArrayIndex(&index)) {
- return js_object->SetElement(index, *value, strict_mode);
+ return js_object->SetElement(index, *value, strict_mode, true);
} else {
return js_object->SetProperty(*name, *value, attr, strict_mode);
}
@@ -4058,12 +4073,12 @@
return *value;
}
- return js_object->SetElement(index, *value, kNonStrictMode);
+ return js_object->SetElement(index, *value, kNonStrictMode, true);
}
if (key->IsString()) {
if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
- return js_object->SetElement(index, *value, kNonStrictMode);
+ return js_object->SetElement(index, *value, kNonStrictMode, true);
} else {
Handle<String> key_string = Handle<String>::cast(key);
key_string->TryFlatten();
@@ -4080,7 +4095,7 @@
Handle<String> name = Handle<String>::cast(converted);
if (name->AsArrayIndex(&index)) {
- return js_object->SetElement(index, *value, kNonStrictMode);
+ return js_object->SetElement(index, *value, kNonStrictMode, true);
} else {
return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
}
@@ -7334,6 +7349,103 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+
+ Handle<JSFunction> callee = args.at<JSFunction>(0);
+ Object** parameters = reinterpret_cast<Object**>(args[1]);
+ const int argument_count = Smi::cast(args[2])->value();
+
+ Handle<JSObject> result =
+ isolate->factory()->NewArgumentsObject(callee, argument_count);
+ // Allocate the elements if needed.
+ int parameter_count = callee->shared()->formal_parameter_count();
+ if (argument_count > 0) {
+ if (parameter_count > 0) {
+ int mapped_count = Min(argument_count, parameter_count);
+ Handle<FixedArray> parameter_map =
+ isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
+ parameter_map->set_map(
+ isolate->heap()->non_strict_arguments_elements_map());
+
+ Handle<Map> old_map(result->map());
+ Handle<Map> new_map =
+ isolate->factory()->CopyMapDropTransitions(old_map);
+ new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS);
+
+ result->set_map(*new_map);
+ result->set_elements(*parameter_map);
+
+ // Store the context and the arguments array at the beginning of the
+ // parameter map.
+ Handle<Context> context(isolate->context());
+ Handle<FixedArray> arguments =
+ isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
+ parameter_map->set(0, *context);
+ parameter_map->set(1, *arguments);
+
+ // Loop over the actual parameters backwards.
+ int index = argument_count - 1;
+ while (index >= mapped_count) {
+ // These go directly in the arguments array and have no
+ // corresponding slot in the parameter map.
+ arguments->set(index, *(parameters - index - 1));
+ --index;
+ }
+
+ ScopeInfo<> scope_info(callee->shared()->scope_info());
+ while (index >= 0) {
+ // Detect duplicate names to the right in the parameter list.
+ Handle<String> name = scope_info.parameter_name(index);
+ int context_slot_count = scope_info.number_of_context_slots();
+ bool duplicate = false;
+ for (int j = index + 1; j < parameter_count; ++j) {
+ if (scope_info.parameter_name(j).is_identical_to(name)) {
+ duplicate = true;
+ break;
+ }
+ }
+
+ if (duplicate) {
+ // This goes directly in the arguments array with a hole in the
+ // parameter map.
+ arguments->set(index, *(parameters - index - 1));
+ parameter_map->set_the_hole(index + 2);
+ } else {
+ // The context index goes in the parameter map with a hole in the
+ // arguments array.
+ int context_index = -1;
+ for (int j = Context::MIN_CONTEXT_SLOTS;
+ j < context_slot_count;
+ ++j) {
+ if (scope_info.context_slot_name(j).is_identical_to(name)) {
+ context_index = j;
+ break;
+ }
+ }
+ ASSERT(context_index >= 0);
+ arguments->set_the_hole(index);
+ parameter_map->set(index + 2, Smi::FromInt(context_index));
+ }
+
+ --index;
+ }
+ } else {
+ // If there is no aliasing, the arguments object elements are not
+ // special in any way.
+ Handle<FixedArray> elements =
+ isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
+ result->set_elements(*elements);
+ for (int i = 0; i < argument_count; ++i) {
+ elements->set(i, *(parameters - i - 1));
+ }
+ }
+ }
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NewStrictArgumentsFast) {
NoHandleAllocation ha;
ASSERT(args.length() == 3);
@@ -7376,10 +7488,8 @@
CONVERT_ARG_CHECKED(SharedFunctionInfo, shared, 1);
CONVERT_BOOLEAN_CHECKED(pretenure, args[2]);
- // Allocate global closures in old space and allocate local closures
- // in new space. Additionally pretenure closures that are assigned
+ // The caller ensures that we pretenure closures that are assigned
// directly to properties.
- pretenure = pretenure || (context->global_context() == *context);
PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
Handle<JSFunction> result =
isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
@@ -7499,7 +7609,7 @@
// If function should not have prototype, construction is not allowed. In this
// case generated code bailouts here, since function has no initial_map.
- if (!function->should_have_prototype()) {
+ if (!function->should_have_prototype() && !function->shared()->bound()) {
Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
Handle<Object> type_error =
isolate->factory()->NewTypeError("not_constructor", arguments);
@@ -7775,7 +7885,7 @@
CONVERT_ARG_CHECKED(JSFunction, function, 0);
// We're not prepared to handle a function with arguments object.
- ASSERT(!function->shared()->scope_info()->HasArgumentsShadow());
+ ASSERT(!function->shared()->uses_arguments());
// We have hit a back edge in an unoptimized frame for a function that was
// selected for on-stack replacement. Find the unoptimized code object.
@@ -8740,8 +8850,8 @@
}
Object* obj;
// Strict not needed. Used for cycle detection in Array join implementation.
- { MaybeObject* maybe_obj = array->SetFastElement(length, element,
- kNonStrictMode);
+ { MaybeObject* maybe_obj =
+ array->SetFastElement(length, element, kNonStrictMode, true);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
return isolate->heap()->true_value();
@@ -10052,18 +10162,14 @@
int context_index = serialized_scope_info->ContextSlotIndex(
*scope_info.context_slot_name(i), NULL);
- // Don't include the arguments shadow (.arguments) context variable.
- if (*scope_info.context_slot_name(i) !=
- isolate->heap()->arguments_shadow_symbol()) {
- RETURN_IF_EMPTY_HANDLE_VALUE(
- isolate,
- SetProperty(scope_object,
- scope_info.context_slot_name(i),
- Handle<Object>(context->get(context_index), isolate),
- NONE,
- kNonStrictMode),
- false);
- }
+ RETURN_IF_EMPTY_HANDLE_VALUE(
+ isolate,
+ SetProperty(scope_object,
+ scope_info.context_slot_name(i),
+ Handle<Object>(context->get(context_index), isolate),
+ NONE,
+ kNonStrictMode),
+ false);
}
return true;
@@ -10158,29 +10264,6 @@
Handle<JSObject> closure_scope =
isolate->factory()->NewJSObject(isolate->object_function());
- // Check whether the arguments shadow object exists.
- int arguments_shadow_index =
- shared->scope_info()->ContextSlotIndex(
- isolate->heap()->arguments_shadow_symbol(), NULL);
- if (arguments_shadow_index >= 0) {
- // In this case all the arguments are available in the arguments shadow
- // object.
- Handle<JSObject> arguments_shadow(
- JSObject::cast(context->get(arguments_shadow_index)));
- for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
- // We don't expect exception-throwing getters on the arguments shadow.
- Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked();
- RETURN_IF_EMPTY_HANDLE_VALUE(
- isolate,
- SetProperty(closure_scope,
- scope_info.parameter_name(i),
- Handle<Object>(element, isolate),
- NONE,
- kNonStrictMode),
- Handle<JSObject>());
- }
- }
-
// Fill all context locals to the context extension.
if (!CopyContextLocalsToScopeObject(isolate,
serialized_scope_info, scope_info,