Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

joyent/mdb_v8#23 support V8 4.4.x and 4.5.x #24

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

## Unreleased changes

* #23 support V8 4.4.x and 4.5.x

* #25 fix ia32 build

* #20 want ::jsfunctions -l
Expand Down
105 changes: 87 additions & 18 deletions src/mdb_v8.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ intptr_t V8_NotStringTag;
intptr_t V8_StringEncodingMask;
intptr_t V8_TwoByteStringTag;
intptr_t V8_AsciiStringTag;
intptr_t V8_OneByteStringTag;
intptr_t V8_StringRepresentationMask;
intptr_t V8_SeqStringTag;
intptr_t V8_ConsStringTag;
Expand All @@ -130,8 +131,8 @@ static intptr_t V8_DICT_SHIFT;
static intptr_t V8_DICT_PREFIX_SIZE;
static intptr_t V8_DICT_ENTRY_SIZE;
static intptr_t V8_DICT_START_INDEX;
static intptr_t V8_FIELDINDEX_MASK;
static intptr_t V8_FIELDINDEX_SHIFT;
static intptr_t V8_PROPINDEX_MASK;
static intptr_t V8_PROPINDEX_SHIFT;
static intptr_t V8_PROP_IDX_CONTENT;
static intptr_t V8_PROP_IDX_FIRST;
static intptr_t V8_PROP_TYPE_FIELD;
Expand Down Expand Up @@ -168,6 +169,7 @@ intptr_t V8_CONTEXT_IDX_GLOBAL;

intptr_t V8_SCOPEINFO_IDX_NPARAMS;
intptr_t V8_SCOPEINFO_IDX_NSTACKLOCALS;
intptr_t V8_SCOPEINFO_OFFSET_STACK_LOCALS;
intptr_t V8_SCOPEINFO_IDX_NCONTEXTLOCALS;
intptr_t V8_SCOPEINFO_IDX_FIRST_VARS;

Expand Down Expand Up @@ -225,13 +227,14 @@ ssize_t V8_OFF_STRING_LENGTH;
#define V8_CONSTANT_OPTIONAL 1
#define V8_CONSTANT_HASFALLBACK 2
#define V8_CONSTANT_REMOVED 4
#define V8_CONSTANT_ADDED 8

#define V8_CONSTANT_MAJORSHIFT 3
#define V8_CONSTANT_MAJORSHIFT 4
#define V8_CONSTANT_MAJORMASK ((1 << 4) - 1)
#define V8_CONSTANT_MAJOR(flags) \
(((flags) >> V8_CONSTANT_MAJORSHIFT) & V8_CONSTANT_MAJORMASK)

#define V8_CONSTANT_MINORSHIFT 7
#define V8_CONSTANT_MINORSHIFT 8
#define V8_CONSTANT_MINORMASK ((1 << 9) - 1)
#define V8_CONSTANT_MINOR(flags) \
(((flags) >> V8_CONSTANT_MINORSHIFT) & V8_CONSTANT_MINORMASK)
Expand All @@ -244,6 +247,10 @@ ssize_t V8_OFF_STRING_LENGTH;
(V8_CONSTANT_REMOVED | \
((maj) << V8_CONSTANT_MAJORSHIFT) | ((min) << V8_CONSTANT_MINORSHIFT))

#define V8_CONSTANT_ADDED_SINCE(maj, min) \
(V8_CONSTANT_ADDED | \
((maj) << V8_CONSTANT_MAJORSHIFT) | ((min) << V8_CONSTANT_MINORSHIFT))

/*
* Table of constants used directly by this file.
*/
Expand All @@ -266,7 +273,10 @@ static v8_constant_t v8_constants[] = {
{ &V8_NotStringTag, "v8dbg_NotStringTag" },
{ &V8_StringEncodingMask, "v8dbg_StringEncodingMask" },
{ &V8_TwoByteStringTag, "v8dbg_TwoByteStringTag" },
{ &V8_AsciiStringTag, "v8dbg_AsciiStringTag" },
{ &V8_AsciiStringTag, "v8dbg_AsciiStringTag",
V8_CONSTANT_REMOVED_SINCE(3, 29) },
{ &V8_OneByteStringTag, "v8dbg_OneByteStringTag",
V8_CONSTANT_ADDED_SINCE(3, 29) },
{ &V8_StringRepresentationMask, "v8dbg_StringRepresentationMask" },
{ &V8_SeqStringTag, "v8dbg_SeqStringTag" },
{ &V8_ConsStringTag, "v8dbg_ConsStringTag" },
Expand Down Expand Up @@ -298,9 +308,9 @@ static v8_constant_t v8_constants[] = {
V8_CONSTANT_FALLBACK(3, 11), 3 },
{ &V8_DICT_START_INDEX, "v8dbg_dict_start_index",
V8_CONSTANT_FALLBACK(3, 11), 3 },
{ &V8_FIELDINDEX_MASK, "v8dbg_fieldindex_mask",
{ &V8_PROPINDEX_MASK, "v8dbg_propindex_mask",
V8_CONSTANT_FALLBACK(3, 26), 0x3ff00000 },
{ &V8_FIELDINDEX_SHIFT, "v8dbg_fieldindex_shift",
{ &V8_PROPINDEX_SHIFT, "v8dbg_propindex_shift",
V8_CONSTANT_FALLBACK(3, 26), 20 },
{ &V8_ISSHARED_SHIFT, "v8dbg_isshared_shift",
V8_CONSTANT_FALLBACK(3, 11), 0 },
Expand Down Expand Up @@ -346,14 +356,17 @@ static v8_constant_t v8_constants[] = {
V8_CONSTANT_FALLBACK(0, 0), 3 },

{ &V8_SCOPEINFO_IDX_NPARAMS, "v8dbg_scopeinfo_idx_nparams",
V8_CONSTANT_FALLBACK(0, 0), 1 },
V8_CONSTANT_FALLBACK(3, 7), 1 },
{ &V8_SCOPEINFO_IDX_NSTACKLOCALS, "v8dbg_scopeinfo_idx_nstacklocals",
V8_CONSTANT_FALLBACK(0, 0), 2 },
V8_CONSTANT_FALLBACK(3, 7), 2 },
{ &V8_SCOPEINFO_OFFSET_STACK_LOCALS,
"v8dbg_scopeinfo_offset_stack_locals",
V8_CONSTANT_FALLBACK(4, 4), 1 },
{ &V8_SCOPEINFO_IDX_NCONTEXTLOCALS,
"v8dbg_scopeinfo_idx_ncontextlocals",
V8_CONSTANT_FALLBACK(0, 0), 3 },
V8_CONSTANT_FALLBACK(3, 7), 3 },
{ &V8_SCOPEINFO_IDX_FIRST_VARS, "v8dbg_scopeinfo_idx_first_vars",
V8_CONSTANT_FALLBACK(0, 0), 4 },
V8_CONSTANT_FALLBACK(4, 5), 6 },
};

static int v8_nconstants = sizeof (v8_constants) / sizeof (v8_constants[0]);
Expand All @@ -363,6 +376,7 @@ typedef struct v8_offset {
const char *v8o_class;
const char *v8o_member;
boolean_t v8o_optional;
uint32_t v8o_flags;
} v8_offset_t;

static v8_offset_t v8_offsets[] = {
Expand Down Expand Up @@ -399,7 +413,11 @@ static v8_offset_t v8_offsets[] = {
{ &V8_OFF_JSREGEXP_DATA,
"JSRegExp", "data", B_TRUE },
{ &V8_OFF_MAP_CONSTRUCTOR,
"Map", "constructor" },
"Map", "constructor",
B_FALSE, V8_CONSTANT_REMOVED_SINCE(4, 3)},
{ &V8_OFF_MAP_CONSTRUCTOR,
"Map", "constructor_or_backpointer",
B_FALSE, V8_CONSTANT_ADDED_SINCE(4, 3)},
{ &V8_OFF_MAP_INOBJECT_PROPERTIES,
"Map", "inobject_properties" },
{ &V8_OFF_MAP_INSTANCE_ATTRIBUTES,
Expand Down Expand Up @@ -539,6 +557,18 @@ v8_version_older(uintptr_t v8_major, uintptr_t v8_minor, uint32_t flags) {
v8_minor < V8_CONSTANT_MINOR(flags)));
}

/*
* Returns 1 if the V8 version v8_major.v8.minor is newer or equal than
* the V8 version represented by "flags".
* Returns 0 otherwise.
*/
static int
v8_version_at_least(uintptr_t v8_major, uintptr_t v8_minor, uint32_t flags) {
return (v8_major > V8_CONSTANT_MAJOR(flags) ||
(v8_major == V8_CONSTANT_MAJOR(flags) &&
v8_minor >= V8_CONSTANT_MINOR(flags)));
}

/*
* Invoked when this dmod is initially loaded to load the set of classes, enums,
* and other constants from the metadata in the target binary.
Expand All @@ -551,6 +581,9 @@ autoconfigure(v8_cfg_t *cfgp)
struct v8_constant *cnp;
int ii;
int failed = 0;
int constant_optional, constant_removed, constant_added;
int offset_optional, offset_removed, offset_added;
int v8_older, v8_at_least;

assert(v8_classes == NULL);

Expand Down Expand Up @@ -585,9 +618,16 @@ autoconfigure(v8_cfg_t *cfgp)
continue;
}

if (!(cnp->v8c_flags & V8_CONSTANT_OPTIONAL) &&
(!(cnp->v8c_flags & V8_CONSTANT_REMOVED) ||
v8_version_older(v8_major, v8_minor, cnp->v8c_flags))) {
constant_optional = cnp->v8c_flags & V8_CONSTANT_OPTIONAL;
constant_removed = cnp->v8c_flags & V8_CONSTANT_REMOVED;
constant_added = cnp->v8c_flags & V8_CONSTANT_ADDED;
v8_older = v8_version_older(v8_major, v8_minor, cnp->v8c_flags);
v8_at_least = v8_version_at_least(v8_major,
v8_minor, cnp->v8c_flags);

if (!constant_optional &&
(!constant_removed || v8_older) &&
(!constant_added || v8_at_least)) {
mdb_warn("failed to read \"%s\"", cnp->v8c_symbol);
failed++;
continue;
Expand Down Expand Up @@ -712,9 +752,20 @@ autoconfigure(v8_cfg_t *cfgp)
continue;
}

mdb_warn("couldn't find class \"%s\", field \"%s\"\n",
offp->v8o_class, offp->v8o_member);
failed++;
offset_optional = offp->v8o_flags & V8_CONSTANT_OPTIONAL;
offset_removed = offp->v8o_flags & V8_CONSTANT_REMOVED;
offset_added = offp->v8o_flags & V8_CONSTANT_ADDED;
v8_older = v8_version_older(v8_major, v8_minor, cnp->v8c_flags);
v8_at_least = v8_version_at_least(v8_major,
v8_minor, offp->v8o_flags);

if (!offset_optional &&
(!offset_removed || v8_older) &&
(!offset_added || v8_at_least)) {
mdb_warn("couldn't find class \"%s\", field \"%s\"\n",
offp->v8o_class, offp->v8o_member);
failed++;
}
}

if (!((V8_OFF_SEQASCIISTR_CHARS != -1) ^
Expand Down Expand Up @@ -758,6 +809,24 @@ autoconfigure(v8_cfg_t *cfgp)
if (V8_OFF_MAP_BIT_FIELD2 == -1)
V8_OFF_MAP_BIT_FIELD2 = V8_OFF_MAP_INSTANCE_ATTRIBUTES + 3;

/*
* V8_SCOPEINFO_IDX_FIRST_VARS' value was 4 in V8 3.7 and up,
* then 5 when StrongModeFreeVariableCount was added with
* https://codereview.chromium.org/1005063002, and 6 when
* ContextGlobalCount was added with
* https://codereview.chromium.org/1218783005.
* Since the current V8_CONSTANT_FALLBACK macro doesn't allow
* us to specify different values for different V8 versions,
* these are hardcoded below.
*/
if (V8_SCOPEINFO_IDX_FIRST_VARS == -1) {
if (v8_major > 4 || (v8_major == 4 && v8_minor >= 3)) {
V8_SCOPEINFO_IDX_FIRST_VARS = 5;
} else if (v8_major > 3 || (v8_major == 3 && v8_minor >= 7)) {
V8_SCOPEINFO_IDX_FIRST_VARS = 4;
}
}

return (failed ? -1 : 0);
}

Expand Down
41 changes: 38 additions & 3 deletions src/mdb_v8_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,13 @@ typedef struct {
v8scopeinfo_vartype_t v8vti_vartype;
const char *v8vti_label;
intptr_t *v8vti_idx_countp;
intptr_t *v8vti_offset;
} v8scopeinfo_vartype_info_t;

static v8scopeinfo_vartype_info_t v8scopeinfo_vartypes[] = {
{ V8SV_PARAMS, "parameter", &V8_SCOPEINFO_IDX_NPARAMS },
{ V8SV_STACKLOCALS, "stack local variable",
&V8_SCOPEINFO_IDX_NSTACKLOCALS },
&V8_SCOPEINFO_IDX_NSTACKLOCALS, &V8_SCOPEINFO_OFFSET_STACK_LOCALS },
{ V8SV_CONTEXTLOCALS, "context local variable",
&V8_SCOPEINFO_IDX_NCONTEXTLOCALS },
};
Expand Down Expand Up @@ -385,13 +386,47 @@ v8scopeinfo_iter_vars(v8scopeinfo_t *sip,
assert(vtip != NULL);
nvars = v8scopeinfo_vartype_nvars(sip, scopevartype);

/*
* Skip to the start of the ScopeInfo's dynamic part. See mdb_v8_db.h
* for more details on the layout of ScopeInfo objects.
*/
nskip = V8_SCOPEINFO_IDX_FIRST_VARS;

/*
* Iterate over variable types so that we can add the offset from the
* beginning of the actual data (the dynamic part) to the region of the
* dynamic part that is specific to the variable type we're interested
* in.
*/
for (i = 0; i < v8scopeinfo_nvartypes; i++) {
ogrp = &v8scopeinfo_vartypes[i];
if (*(ogrp->v8vti_idx_countp) >= *(vtip->v8vti_idx_countp)) {
continue;

/*
* In the variable/dynamic part of a ScopeInfo layout, some
* variable types have static metadata, e.g stack local entries
* have a StackLocalFirstSlot, before the actual data. Add that
* offset for each variable type, including for the one we're
* interested in.
*/
if (v8scopeinfo_vartypes[i].v8vti_offset != NULL &&
*(v8scopeinfo_vartypes[i].v8vti_offset) != -1) {
nskip += *(v8scopeinfo_vartypes[i].v8vti_offset);
}

/*
* If the current variable type is the one we're interested in,
* do not add anything to the offset. We're done.
*/
if (*(ogrp->v8vti_idx_countp) == *(vtip->v8vti_idx_countp)) {
break;
}

/*
* The data for the current variable type is before the one
* we're interested in in the variable part of the ScopeInfo
* layout. Add the number of entries for this variable type to
* the offset.
*/
nskip += v8scopeinfo_vartype_nvars(sip, ogrp->v8vti_vartype);
}

Expand Down
1 change: 1 addition & 0 deletions src/mdb_v8_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ extern intptr_t V8_SCOPEINFO_IDX_FIRST_VARS;
extern intptr_t V8_SCOPEINFO_IDX_NCONTEXTLOCALS;
extern intptr_t V8_SCOPEINFO_IDX_NPARAMS;
extern intptr_t V8_SCOPEINFO_IDX_NSTACKLOCALS;
extern intptr_t V8_SCOPEINFO_OFFSET_STACK_LOCALS;

extern intptr_t V8_HeapObjectTag;
extern intptr_t V8_HeapObjectTagMask;
Expand Down
7 changes: 5 additions & 2 deletions src/v8dbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@
#define V8_TYPE_STRING(type) (((type) & V8_IsNotStringMask) == V8_StringTag)

#define V8_STRENC_ASCII(type) \
(((type) & V8_StringEncodingMask) == V8_AsciiStringTag)
((V8_AsciiStringTag != -1 && \
((type) & V8_StringEncodingMask) == V8_AsciiStringTag) || \
(V8_OneByteStringTag != -1 && \
((type) & V8_StringEncodingMask) == V8_OneByteStringTag))

#define V8_STRREP_SEQ(type) \
(((type) & V8_StringRepresentationMask) == V8_SeqStringTag)
Expand All @@ -72,6 +75,6 @@
((V8_SMI_VALUE(x) & V8_PROP_TYPE_MASK) == V8_PROP_TYPE_FIELD)

#define V8_PROP_FIELDINDEX(value) \
((V8_SMI_VALUE(value) & V8_FIELDINDEX_MASK) >> V8_FIELDINDEX_SHIFT)
((V8_SMI_VALUE(value) & V8_PROPINDEX_MASK) >> V8_PROPINDEX_SHIFT)

#endif /* _V8DBG_H */
2 changes: 1 addition & 1 deletion test/standalone/tst.postmortem_details.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ gcore.on('exit', function (code) {

var mdb = spawn('mdb', args, { stdio: 'pipe' });

mdb.on('exit', function (code2) {
mdb.stdin.on('end', function (code2) {
unlinkSync(tmpfile);
var retained = '; core retained as ' + corefile;

Expand Down
2 changes: 1 addition & 1 deletion test/standalone/tst.postmortem_findjsobjects.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ gcore.on('exit', function (code) {

var mdb = spawn('mdb', args, { stdio: 'pipe' });

mdb.on('exit', function (code2) {
mdb.stdin.on('end', function (code2) {
var retained = '; core retained as ' + corefile;

if (code2 != 0) {
Expand Down