Revision: 3707
Author: [email protected]
Date: Tue Jan 26 02:26:03 2010
Log: Add code to help diagnose the cause of issue 555.
Review URL: http://codereview.chromium.org/552153
http://code.google.com/p/v8/source/detail?r=3707
Modified:
/branches/experimental/issue555/src/objects.cc
/branches/experimental/issue555/src/runtime.cc
=======================================
--- /branches/experimental/issue555/src/objects.cc Thu Jan 14 07:28:53 2010
+++ /branches/experimental/issue555/src/objects.cc Tue Jan 26 02:26:03 2010
@@ -8302,5 +8302,26 @@
}
#endif
+
+// BUG(555): This function is used to diagnose issue 555 from
+// runtime.cc. We avoid inlining it by placing it here.
+void CaptureInfoForIssue555(
+ bool is_bootstrapping,
+ AllocationSpace context_space,
+ Object* context,
+ Object* context_map,
+ int context_length,
+ Object* context_closure,
+ Object* context_fcontext,
+ Object* context_previous,
+ Object* context_extension,
+ Object* context_global,
+ AllocationSpace function_space,
+ Object* function,
+ bool runs_in_inner_context,
+ bool runs_in_outer_context) {
+ // Kill the virtual machine.
+ OS::Abort();
+}
} } // namespace v8::internal
=======================================
--- /branches/experimental/issue555/src/runtime.cc Mon Jan 25 02:15:52 2010
+++ /branches/experimental/issue555/src/runtime.cc Tue Jan 26 02:26:03 2010
@@ -32,6 +32,7 @@
#include "accessors.h"
#include "api.h"
#include "arguments.h"
+#include "bootstrapper.h"
#include "compiler.h"
#include "cpu.h"
#include "dateparser-inl.h"
@@ -4592,11 +4593,109 @@
}
return result;
}
+
+
+// We avoid inlining this function by placing it in another .cc file.
+extern void CaptureInfoForIssue555(
+ bool is_bootstrapping,
+ AllocationSpace context_space,
+ Object* context,
+ Object* context_map,
+ int context_length,
+ Object* context_closure,
+ Object* context_fcontext,
+ Object* context_previous,
+ Object* context_extension,
+ Object* context_global,
+ AllocationSpace function_space,
+ Object* function,
+ bool runs_in_inner_context,
+ bool runs_in_outer_context);
+
+
+static AllocationSpace ComputeSpace(Object* object) {
+ static const AllocationSpace kIllegalSpace =
static_cast<AllocationSpace>(-1);
+ if (!object->IsHeapObject()) return kIllegalSpace;
+ for (int attempt = FIRST_SPACE; attempt <= LAST_SPACE; attempt++) {
+ AllocationSpace space = static_cast<AllocationSpace>(attempt);
+ if (Heap::InSpace(HeapObject::cast(object), space)) return space;
+ }
+ return kIllegalSpace;
+}
+
+
+static void DiagnoseIssue555(Arguments args) {
+ static const int kUninitialized = 0x12345678;
+ static Object* const kUninitializedObject =
bit_cast<Object*>(kUninitialized);
+
+ // Read the invalid context from the arguments.
+ Object* context = args[0];
+
+ // Compute basic diagnostic information.
+ bool is_bootstrapping = Bootstrapper::IsActive();
+ AllocationSpace context_space = ComputeSpace(context);
+
+ // Get the context map and length.
+ Object* context_map = kUninitializedObject;
+ int context_length = kUninitialized;
+ if (context->IsHeapObject()) {
+ context_map = HeapObject::cast(context)->map();
+ context_length = FixedArray::cast(context)->length();
+ }
+
+ // Get the context slots.
+ Object* context_slots[Context::MIN_CONTEXT_SLOTS];
+ for (int i = 0; i < Context::MIN_CONTEXT_SLOTS; i++) {
+ // Initialize the context slots to a recognizable bit pattern.
+ context_slots[i] = kUninitializedObject;
+ if (context->IsHeapObject()) {
+ context_slots[i] = FixedArray::cast(context)->get(i);
+ }
+ }
+
+ // Check if the function that requested a new closure runs either in
+ // its outer context (set in the function) or in its own dynamically
+ // created inner context.
+ StackFrameLocator locator;
+ JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
+ JSFunction* function = JSFunction::cast(frame->function());
+ AllocationSpace function_space = ComputeSpace(function);
+ bool runs_in_inner_context =
+ (function == context_slots[Context::CLOSURE_INDEX]);
+ bool runs_in_outer_context =
+ (function->context() == context);
+
+ // Capture the diagnostic information by passing the state to an
+ // external function.
+ CaptureInfoForIssue555(
+ is_bootstrapping,
+ context_space,
+ context,
+ context_map,
+ context_length,
+ context_slots[Context::CLOSURE_INDEX],
+ context_slots[Context::FCONTEXT_INDEX],
+ context_slots[Context::PREVIOUS_INDEX],
+ context_slots[Context::EXTENSION_INDEX],
+ context_slots[Context::GLOBAL_INDEX],
+ function_space,
+ function,
+ runs_in_inner_context,
+ runs_in_outer_context);
+}
static Object* Runtime_NewClosure(Arguments args) {
HandleScope scope;
ASSERT(args.length() == 2);
+
+ // BUG(555): Attempt to gather more information about the crash in
+ // NewClosure where the context is invalid. This rarely happens, but
+ // it brings down V8 through a null pointer exception when throwing
+ // an illegal access exception. For more details, see:
+ // http://code.google.com/p/v8/issues/detail?id=555
+ if (!args[0]->IsContext()) DiagnoseIssue555(args);
+
CONVERT_ARG_CHECKED(Context, context, 0);
CONVERT_ARG_CHECKED(JSFunction, boilerplate, 1);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev