Skip to content

Commit edea94c

Browse files
Dave Pachecoisaacs
Dave Pacheco
authored andcommitted
dtrace ustack helper improvements
Fixes #2852
1 parent d8c5ba2 commit edea94c

File tree

2 files changed

+62
-5
lines changed

2 files changed

+62
-5
lines changed

src/v8constants.h

+4
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
* Instance types
5858
*/
5959
#define V8_IT_FIXEDARRAY 0x9f
60+
#define V8_IT_CODE 0x81
6061

6162
/*
6263
* Identification masks and tags
@@ -65,6 +66,9 @@
6566
#define V8_SmiTag 0x0
6667
#define V8_SmiValueShift V8_SmiTagMask
6768

69+
#define V8_HeapObjectTagMask 0x3
70+
#define V8_HeapObjectTag 0x1
71+
6872
#define V8_IsNotStringMask 0x80
6973
#define V8_StringTag 0x0
7074

src/v8ustack.d

+58-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,16 @@
1717
* value. To extract the actual integer value, we must shift it over.
1818
*/
1919
#define IS_SMI(value) ((value & V8_SmiTagMask) == V8_SmiTag)
20-
#define SMI_VALUE(value) ((int32_t)(value) >> V8_SmiValueShift)
20+
#define SMI_VALUE(value) ((uint32_t)(value) >> V8_SmiValueShift)
21+
22+
/*
23+
* Heap objects usually start off with a Map pointer, itself another heap
24+
* object. However, during garbage collection, the low order bits of the
25+
* pointer (which are normally 01) are used to record GC state. Of course, we
26+
* have no idea if we're in GC or not, so we must always normalize the pointer.
27+
*/
28+
#define V8_MAP_PTR(ptr) \
29+
((ptr & ~V8_HeapObjectTagMask) | V8_HeapObjectTag)
2130

2231
/*
2332
* Determine the encoding and representation of a V8 string.
@@ -88,7 +97,7 @@
8897
*/
8998
#define LOAD_STRFIELDS(str, len, attrs) \
9099
len = SMI_VALUE(COPYIN_UINT32(str + V8_OFF_STR_LENGTH)); \
91-
this->map = COPYIN_UINT32(str + V8_OFF_HEAPOBJ_MAP); \
100+
this->map = V8_MAP_PTR(COPYIN_UINT32(str + V8_OFF_HEAPOBJ_MAP)); \
92101
attrs = COPYIN_UINT8(this->map + V8_OFF_MAP_ATTRS);
93102

94103
/*
@@ -170,7 +179,7 @@ dtrace:helper:ustack: \
170179
}
171180

172181
/*
173-
* Expand the ConsString "str" (represensted by "str", "len", and "attrs") into
182+
* Expand the ConsString "str" (represented by "str", "len", and "attrs") into
174183
* strings "s1" (represented by "s1s", "s1l", and "s1a") and "s2" (represented
175184
* by "s2s", "s2l", "s2a"). If "str" is not a ConsString, do nothing.
176185
*/
@@ -261,6 +270,7 @@ dtrace:helper:ustack:
261270
this->func = 0;
262271
this->shared = 0;
263272
this->map = 0;
273+
this->attrs = 0;
264274
this->funcnamestr = 0;
265275
this->funcnamelen = 0;
266276
this->funcnameattrs = 0;
@@ -435,6 +445,46 @@ dtrace:helper:ustack:
435445
stringof(this->buf);
436446
}
437447

448+
/*
449+
* Now check for internal frames that we can only identify by seeing that
450+
* there's a Code object where there would be a JSFunction object for a
451+
* JavaScriptFrame.
452+
*/
453+
dtrace:helper:ustack:
454+
/!this->done/
455+
{
456+
this->func = COPYIN_UINT32(this->fp + V8_OFF_FP_FUNC);
457+
this->map = V8_MAP_PTR(COPYIN_UINT32(this->func + V8_OFF_HEAPOBJ_MAP));
458+
this->attrs = COPYIN_UINT8(this->map + V8_OFF_MAP_ATTRS);
459+
}
460+
461+
dtrace:helper:ustack:
462+
/!this->done && this->attrs == V8_IT_CODE/
463+
{
464+
this->done = 1;
465+
APPEND_CHR('<');
466+
APPEND_CHR('<');
467+
APPEND_CHR(' ');
468+
APPEND_CHR('i');
469+
APPEND_CHR('n');
470+
APPEND_CHR('t');
471+
APPEND_CHR('e');
472+
APPEND_CHR('r');
473+
APPEND_CHR('n');
474+
APPEND_CHR('a');
475+
APPEND_CHR('l');
476+
APPEND_CHR(' ');
477+
APPEND_CHR('c');
478+
APPEND_CHR('o');
479+
APPEND_CHR('d');
480+
APPEND_CHR('e');
481+
APPEND_CHR(' ');
482+
APPEND_CHR('>');
483+
APPEND_CHR('>');
484+
APPEND_CHR('\0');
485+
stringof(this->buf);
486+
}
487+
438488
/*
439489
* At this point, we're either looking at a JavaScriptFrame or an
440490
* OptimizedFrame. For now, we assume JavaScript and start by grabbing the
@@ -443,7 +493,9 @@ dtrace:helper:ustack:
443493
dtrace:helper:ustack:
444494
/!this->done/
445495
{
446-
this->func = COPYIN_UINT32(this->fp + V8_OFF_FP_FUNC);
496+
this->map = 0;
497+
this->attrs = 0;
498+
447499
this->shared = COPYIN_UINT32(this->func + V8_OFF_FUNC_SHARED);
448500
this->funcnamestr = COPYIN_UINT32(this->shared + V8_OFF_SHARED_NAME);
449501
LOAD_STRFIELDS(this->funcnamestr, this->funcnamelen,
@@ -515,7 +567,8 @@ dtrace:helper:ustack:
515567
{
516568
this->position = COPYIN_UINT32(this->shared + V8_OFF_SHARED_FUNTOK);
517569
this->line_ends = COPYIN_UINT32(this->script + V8_OFF_SCRIPT_LENDS);
518-
this->map = COPYIN_UINT32(this->line_ends + V8_OFF_HEAPOBJ_MAP);
570+
this->map = V8_MAP_PTR(COPYIN_UINT32(this->line_ends +
571+
V8_OFF_HEAPOBJ_MAP));
519572
this->le_attrs = COPYIN_UINT8(this->map + V8_OFF_MAP_ATTRS);
520573
}
521574

0 commit comments

Comments
 (0)