Reviewers: ulan,
Description:
Add --trace-array-abuse to help find OOB accesses.
[email protected]
Please review this at https://codereview.chromium.org/12220040/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/elements.h
M src/elements.cc
M src/flag-definitions.h
M src/objects.cc
M test/mjsunit/compiler/array-access.js
Index: src/elements.cc
diff --git a/src/elements.cc b/src/elements.cc
index
5b454e5964ae2caf873f30adc7ddc83b1f6f08c8..6459279dea56753cbbdfa194678d77c0cb6b11ea
100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -30,7 +30,7 @@
#include "objects.h"
#include "elements.h"
#include "utils.h"
-
+#include "v8conversions.h"
// Each concrete ElementsAccessor can handle exactly one ElementsKind,
// several abstract ElementsAccessor classes are used to allow sharing
@@ -483,6 +483,63 @@ static void
CopyDictionaryToDoubleElements(FixedArrayBase* from_base,
}
+static void TraceTopFrame() {
+ StackFrameIterator it;
+ if (it.done()) {
+ PrintF("unknown location (no JavaScript frames present)");
+ return;
+ }
+ StackFrame* raw_frame = it.frame();
+ if (raw_frame->is_internal()) {
+ Isolate* isolate = Isolate::Current();
+ Code* apply_builtin = isolate->builtins()->builtin(
+ Builtins::kFunctionApply);
+ if (raw_frame->unchecked_code() == apply_builtin) {
+ PrintF("apply from ");
+ it.Advance();
+ raw_frame = it.frame();
+ }
+ }
+ JavaScriptFrame::PrintTop(stdout, false, true);
+}
+
+
+void CheckArrayAbuse(JSObject* obj, const char* op, uint32_t key) {
+ Object* raw_length = NULL;
+ const char* elements_type = "array";
+ if (obj->IsJSArray()) {
+ JSArray* array = JSArray::cast(obj);
+ raw_length = array->length();
+ } else {
+ raw_length = Smi::FromInt(obj->elements()->length());
+ elements_type = "object";
+ }
+
+ if (raw_length->IsNumber()) {
+ double n = raw_length->Number();
+ if (FastI2D(FastD2UI(n)) == n) {
+ int32_t int32_length = DoubleToInt32(n);
+ if (key >= static_cast<uint32_t>(int32_length)) {
+ PrintF("[OOB %s %s (%s length = %d, element accessed = %d) in ",
+ elements_type, op, elements_type,
+ static_cast<int>(int32_length),
+ static_cast<int>(key));
+ TraceTopFrame();
+ PrintF("]\n");
+ }
+ } else {
+ PrintF("[%s elements length not integer value in ", elements_type);
+ TraceTopFrame();
+ PrintF("]\n");
+ }
+ } else {
+ PrintF("[%s elements length not a number in ", elements_type);
+ TraceTopFrame();
+ PrintF("]\n");
+ }
+}
+
+
// Base class for element handler implementations. Contains the
// the common logic for objects with different ElementsKinds.
// Subclasses must specialize method for which the element
@@ -570,6 +627,11 @@ class ElementsAccessorBase : public ElementsAccessor {
if (backing_store == NULL) {
backing_store = holder->elements();
}
+
+ if (FLAG_trace_array_abuse) {
+ CheckArrayAbuse(holder, "element read", key);
+ }
+
return ElementsAccessorSubclass::GetImpl(
receiver, holder, key, backing_store);
}
Index: src/elements.h
diff --git a/src/elements.h b/src/elements.h
index
e25076ba5c6ed1d527207dbe3a7c6f7b226c37e9..167fb91197b024453e711cf7687f5d5a09e0d48a
100644
--- a/src/elements.h
+++ b/src/elements.h
@@ -197,6 +197,8 @@ class ElementsAccessor {
DISALLOW_COPY_AND_ASSIGN(ElementsAccessor);
};
+void CheckArrayAbuse(JSObject* obj, const char* op, uint32_t key);
+
} } // namespace v8::internal
#endif // V8_ELEMENTS_H_
Index: src/flag-definitions.h
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index
4a0d3c661a24cb6ecd292441f53fcb11d16941ee..747e7c1f3c131d041785b876ca5587e86565f7ed
100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -363,6 +363,7 @@ DEFINE_bool(cache_prototype_transitions, true, "cache
prototype transitions")
// debug.cc
DEFINE_bool(trace_debug_json, false, "trace debugging JSON
request/response")
+DEFINE_bool(trace_array_abuse, false, "trace out-of-bounds array accesses")
DEFINE_bool(debugger_auto_break, true,
"automatically set the debug break flag when debugger commands
are "
"in the queue")
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
46539311de9625d9c7ffccc54bd476ab5510a47b..b3a5658ca03181502734054f0a640d4a75a854e6
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -10405,6 +10405,11 @@ MaybeObject*
JSObject::SetElementWithoutInterceptor(uint32_t index,
HasDictionaryArgumentsElements() ||
(attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0);
Isolate* isolate = GetIsolate();
+ if (FLAG_trace_array_abuse) {
+ if (IsExternalArrayElementsKind(GetElementsKind())) {
+ CheckArrayAbuse(this, "external elements write", index);
+ }
+ }
switch (GetElementsKind()) {
case FAST_SMI_ELEMENTS:
case FAST_ELEMENTS:
Index: test/mjsunit/compiler/array-access.js
diff --git a/test/mjsunit/compiler/array-access.js
b/test/mjsunit/compiler/array-access.js
index
65b3c99b422872d0f24f5cf7b2d67f567d3373f4..cdad595cdf08ae9cca30dcab80fc55a4d792cdb3
100644
--- a/test/mjsunit/compiler/array-access.js
+++ b/test/mjsunit/compiler/array-access.js
@@ -130,3 +130,9 @@ for (var i = 0; i < 1000; i++) {
}
RunArrayBoundsCheckTest();
+
+a = new Array();
+a[3];
+
+a = new Float32Array(2);
+a[3] = 5;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.