Version 2.0.3
Optimized handling and adding of strings, for-in and Array.join.
Heap serialization is now non-destructive.
Improved profiler support with information on time spend in C++ callbacks registered through the API.
Added commands to the debugger protocol for starting/stopping profiling.
Enabled the non-optimizing compiler for top-level code.
Changed the API to only allow strings to be set as data objects on Contexts and scripts to avoid potentially keeping global objects around for too long (issue 528).
OpenBSD support patch by Peter Valchev <pvalchev@gmail.com>.
Fixed bugs.
git-svn-id: http://v8.googlecode.com/svn/trunk@3423 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/runtime.cc b/src/runtime.cc
index 6ae2233..65dfd13 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -788,51 +788,72 @@
// case of callbacks in the prototype chain (this rules out using
// SetProperty). We have IgnoreAttributesAndSetLocalProperty for
// this.
+ // Note that objects can have hidden prototypes, so we need to traverse
+ // the whole chain of hidden prototypes to do a 'local' lookup.
+ JSObject* real_holder = global;
LookupResult lookup;
- global->LocalLookup(*name, &lookup);
- if (!lookup.IsProperty()) {
- if (assign) {
- return global->IgnoreAttributesAndSetLocalProperty(*name,
- args[1],
- attributes);
+ while (true) {
+ real_holder->LocalLookup(*name, &lookup);
+ if (lookup.IsProperty()) {
+ // Determine if this is a redeclaration of something read-only.
+ if (lookup.IsReadOnly()) {
+ // If we found readonly property on one of hidden prototypes,
+ // just shadow it.
+ if (real_holder != Top::context()->global()) break;
+ return ThrowRedeclarationError("const", name);
+ }
+
+ // Determine if this is a redeclaration of an intercepted read-only
+ // property and figure out if the property exists at all.
+ bool found = true;
+ PropertyType type = lookup.type();
+ if (type == INTERCEPTOR) {
+ HandleScope handle_scope;
+ Handle<JSObject> holder(real_holder);
+ PropertyAttributes intercepted = holder->GetPropertyAttribute(*name);
+ real_holder = *holder;
+ if (intercepted == ABSENT) {
+ // The interceptor claims the property isn't there. We need to
+ // make sure to introduce it.
+ found = false;
+ } else if ((intercepted & READ_ONLY) != 0) {
+ // The property is present, but read-only. Since we're trying to
+ // overwrite it with a variable declaration we must throw a
+ // re-declaration error. However if we found readonly property
+ // on one of hidden prototypes, just shadow it.
+ if (real_holder != Top::context()->global()) break;
+ return ThrowRedeclarationError("const", name);
+ }
+ }
+
+ if (found && !assign) {
+ // The global property is there and we're not assigning any value
+ // to it. Just return.
+ return Heap::undefined_value();
+ }
+
+ // Assign the value (or undefined) to the property.
+ Object* value = (assign) ? args[1] : Heap::undefined_value();
+ return real_holder->SetProperty(&lookup, *name, value, attributes);
}
- return Heap::undefined_value();
+
+ Object* proto = real_holder->GetPrototype();
+ if (!proto->IsJSObject())
+ break;
+
+ if (!JSObject::cast(proto)->map()->is_hidden_prototype())
+ break;
+
+ real_holder = JSObject::cast(proto);
}
- // Determine if this is a redeclaration of something read-only.
- if (lookup.IsReadOnly()) {
- return ThrowRedeclarationError("const", name);
+ global = Top::context()->global();
+ if (assign) {
+ return global->IgnoreAttributesAndSetLocalProperty(*name,
+ args[1],
+ attributes);
}
-
- // Determine if this is a redeclaration of an intercepted read-only
- // property and figure out if the property exists at all.
- bool found = true;
- PropertyType type = lookup.type();
- if (type == INTERCEPTOR) {
- PropertyAttributes intercepted = global->GetPropertyAttribute(*name);
- if (intercepted == ABSENT) {
- // The interceptor claims the property isn't there. We need to
- // make sure to introduce it.
- found = false;
- } else if ((intercepted & READ_ONLY) != 0) {
- // The property is present, but read-only. Since we're trying to
- // overwrite it with a variable declaration we must throw a
- // re-declaration error.
- return ThrowRedeclarationError("const", name);
- }
- // Restore global object from context (in case of GC).
- global = Top::context()->global();
- }
-
- if (found && !assign) {
- // The global property is there and we're not assigning any value
- // to it. Just return.
- return Heap::undefined_value();
- }
-
- // Assign the value (or undefined) to the property.
- Object* value = (assign) ? args[1] : Heap::undefined_value();
- return global->SetProperty(&lookup, *name, value, attributes);
+ return Heap::undefined_value();
}
@@ -3762,6 +3783,7 @@
ASSERT(args.length() == 2);
CONVERT_CHECKED(String, str1, args[0]);
CONVERT_CHECKED(String, str2, args[1]);
+ Counters::string_add_runtime.Increment();
return Heap::AllocateConsString(str1, str2);
}
@@ -4987,6 +5009,9 @@
PrintF("DebugPrint: ");
}
args[0]->Print();
+ if (args[0]->IsHeapObject()) {
+ HeapObject::cast(args[0])->map()->Print();
+ }
#else
// ShortPrint is available in release mode. Print is not.
args[0]->ShortPrint();
@@ -7667,8 +7692,31 @@
CONVERT_CHECKED(JSFunction, f, args[0]);
return f->shared()->inferred_name();
}
+
#endif // ENABLE_DEBUGGER_SUPPORT
+#ifdef ENABLE_LOGGING_AND_PROFILING
+
+static Object* Runtime_ProfilerResume(Arguments args) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 1);
+
+ CONVERT_CHECKED(Smi, smi_modules, args[0]);
+ v8::V8::ResumeProfilerEx(smi_modules->value());
+ return Heap::undefined_value();
+}
+
+
+static Object* Runtime_ProfilerPause(Arguments args) {
+ NoHandleAllocation ha;
+ ASSERT(args.length() == 1);
+
+ CONVERT_CHECKED(Smi, smi_modules, args[0]);
+ v8::V8::PauseProfilerEx(smi_modules->value());
+ return Heap::undefined_value();
+}
+
+#endif // ENABLE_LOGGING_AND_PROFILING
// Finds the script object from the script data. NOTE: This operation uses
// heap traversal to find the function generated for the source position