Version 3.5.4
Added preliminary implementation of ES Harmony weak maps. Weak maps can be enabled by the flag --harmony_weakmaps.
Introduced a toplevel Makefile to support GYP-based building. GYP can be found at http://gyp.googlecode.com.
Fixed a bug in the length property of functions created by Function.prototype.bind.
Reduced malloc heap allocation on process startup.
Several important code generation bug fixes.
Performance improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@8874 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/runtime.cc b/src/runtime.cc
index 8c43d64..82733a7 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -615,8 +615,7 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) {
ASSERT(args.length() == 1);
Object* obj = args[0];
- return obj->IsJSProxy()
- ? isolate->heap()->true_value() : isolate->heap()->false_value();
+ return isolate->heap()->ToBoolean(obj->IsJSProxy());
}
@@ -635,6 +634,43 @@
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
+ ASSERT(weakmap->map()->inobject_properties() == 0);
+ Handle<ObjectHashTable> table = isolate->factory()->NewObjectHashTable(0);
+ weakmap->set_table(*table);
+ weakmap->set_next(Smi::FromInt(0));
+ return *weakmap;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
+ // TODO(mstarzinger): Currently we cannot use JSProxy objects as keys
+ // because they cannot be cast to JSObject to get an identity hash code.
+ CONVERT_ARG_CHECKED(JSObject, key, 1);
+ return weakmap->table()->Lookup(*key);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapSet) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
+ // TODO(mstarzinger): See Runtime_WeakMapGet above.
+ CONVERT_ARG_CHECKED(JSObject, key, 1);
+ Handle<Object> value(args[2]);
+ Handle<ObjectHashTable> table(weakmap->table());
+ Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
+ weakmap->set_table(*new_table);
+ return *value;
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
@@ -1001,8 +1037,7 @@
ASSERT(proto->IsJSGlobalObject());
obj = JSObject::cast(proto);
}
- return obj->map()->is_extensible() ? isolate->heap()->true_value()
- : isolate->heap()->false_value();
+ return isolate->heap()->ToBoolean(obj->map()->is_extensible());
}
@@ -1068,8 +1103,7 @@
Map::cast(new_map)->set_is_access_check_needed(false);
object->set_map(Map::cast(new_map));
}
- return needs_access_checks ? isolate->heap()->true_value()
- : isolate->heap()->false_value();
+ return isolate->heap()->ToBoolean(needs_access_checks);
}
@@ -1880,6 +1914,24 @@
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionNameShouldPrintAsAnonymous) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 1);
+ CONVERT_CHECKED(JSFunction, f, args[0]);
+ return isolate->heap()->ToBoolean(
+ f->shared()->name_should_print_as_anonymous());
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 1);
+ CONVERT_CHECKED(JSFunction, f, args[0]);
+ f->shared()->set_name_should_print_as_anonymous(true);
+ return isolate->heap()->undefined_value();
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetBound) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -1967,6 +2019,24 @@
}
+// Creates a local, readonly, property called length with the correct
+// length (when read by the user). This effectively overwrites the
+// interceptor used to normally provide the length.
+RUNTIME_FUNCTION(MaybeObject*, Runtime_BoundFunctionSetLength) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 2);
+ CONVERT_CHECKED(JSFunction, fun, args[0]);
+ CONVERT_CHECKED(Smi, length, args[1]);
+ MaybeObject* maybe_name =
+ isolate->heap()->AllocateStringFromAscii(CStrVector("length"));
+ String* name;
+ if (!maybe_name->To(&name)) return maybe_name;
+ PropertyAttributes attr =
+ static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
+ return fun->AddProperty(name, length, attr, kNonStrictMode);
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetPrototype) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
@@ -2042,8 +2112,7 @@
ASSERT(args.length() == 1);
CONVERT_CHECKED(JSFunction, f, args[0]);
- return f->shared()->IsApiFunction() ? isolate->heap()->true_value()
- : isolate->heap()->false_value();
+ return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
}
@@ -2052,8 +2121,7 @@
ASSERT(args.length() == 1);
CONVERT_CHECKED(JSFunction, f, args[0]);
- return f->IsBuiltin() ? isolate->heap()->true_value() :
- isolate->heap()->false_value();
+ return isolate->heap()->ToBoolean(f->IsBuiltin());
}
@@ -4529,9 +4597,10 @@
// Get the property names.
jsproto = obj;
int proto_with_hidden_properties = 0;
+ int next_copy_index = 0;
for (int i = 0; i < length; i++) {
- jsproto->GetLocalPropertyNames(*names,
- i == 0 ? 0 : local_property_count[i - 1]);
+ jsproto->GetLocalPropertyNames(*names, next_copy_index);
+ next_copy_index += local_property_count[i];
if (jsproto->HasHiddenProperties()) {
proto_with_hidden_properties++;
}
@@ -9200,13 +9269,13 @@
if (elements_are_guaranteed_smis) {
for (uint32_t j = 0; j < len; j++) {
HandleScope loop_scope;
- Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get(j))));
+ Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))));
visitor->visit(j, e);
}
} else {
for (uint32_t j = 0; j < len; j++) {
HandleScope loop_scope;
- int64_t val = static_cast<int64_t>(array->get(j));
+ int64_t val = static_cast<int64_t>(array->get_scalar(j));
if (Smi::IsValid(static_cast<intptr_t>(val))) {
Handle<Smi> e(Smi::FromInt(static_cast<int>(val)));
visitor->visit(j, e);
@@ -9220,7 +9289,7 @@
} else {
for (uint32_t j = 0; j < len; j++) {
HandleScope loop_scope(isolate);
- Handle<Object> e = isolate->factory()->NewNumber(array->get(j));
+ Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
visitor->visit(j, e);
}
}
@@ -9406,7 +9475,7 @@
Handle<ExternalPixelArray> pixels(ExternalPixelArray::cast(
receiver->elements()));
for (uint32_t j = 0; j < length; j++) {
- Handle<Smi> e(Smi::FromInt(pixels->get(j)));
+ Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)));
visitor->visit(j, e);
}
break;
@@ -9924,9 +9993,7 @@
details->set(0, *value);
details->set(1, property_details);
if (hasJavaScriptAccessors) {
- details->set(2,
- caught_exception ? isolate->heap()->true_value()
- : isolate->heap()->false_value());
+ details->set(2, isolate->heap()->ToBoolean(caught_exception));
details->set(3, FixedArray::cast(*result_callback_obj)->get(0));
details->set(4, FixedArray::cast(*result_callback_obj)->get(1));
}
@@ -11378,7 +11445,11 @@
context->set_extension(*local_scope);
// Copy any with contexts present and chain them in front of this context.
Handle<Context> frame_context(Context::cast(frame->context()));
- Handle<Context> function_context(frame_context->declaration_context());
+ Handle<Context> function_context;
+ // Get the function's context if it has one.
+ if (scope_info->HasHeapAllocatedLocals()) {
+ function_context = Handle<Context>(frame_context->declaration_context());
+ }
context = CopyWithContextChain(isolate, go_between, frame_context, context);
if (additional_context->IsJSObject()) {
@@ -12109,8 +12180,7 @@
#ifdef LIVE_OBJECT_LIST
CONVERT_SMI_ARG_CHECKED(id, 0);
bool success = LiveObjectList::Delete(id);
- return success ? isolate->heap()->true_value() :
- isolate->heap()->false_value();
+ return isolate->heap()->ToBoolean(success);
#else
return isolate->heap()->undefined_value();
#endif