Closed
Bug 542932
Opened 15 years ago
Closed 15 years ago
nanojit: make opcode range checks safer
Categories
(Core Graveyard :: Nanojit, defect)
Tracking
(Not tracked)
RESOLVED
FIXED
People
(Reporter: n.nethercote, Assigned: n.nethercote)
References
Details
(Whiteboard: fixed-in-nanojit, fixed-in-tracemonkey, fixed-in-tamarin)
Attachments
(2 files)
52.87 KB,
patch
|
stejohns
:
review+
|
Details | Diff | Splinter Review |
3.38 KB,
patch
|
gal
:
review+
|
Details | Diff | Splinter Review |
Currently whether an opcode is CSEable is determine by an opcode range check -- opcodes in certain ranges are CSEable. This is awful.
I propose to add a field to LIRopcode.tbl that indicates if an instruction is CSEable. As well as being safer, this will allow opcodes to be numbered much more sensibly, eg. you can put LIR_ldc next to LIR_ld!
Comment 1•15 years ago
|
||
+1
other predicates that check opcode ranges could be candidates too (conditions?).
![]() |
Assignee | |
Comment 2•15 years ago
|
||
For conditions we currently have this:
bool isCmp() const {
LOpcode op = opcode();
return (op >= LIR_eq && op <= LIR_uge) ||
(op >= LIR_qeq && op <= LIR_quge) ||
(op >= LIR_feq && op <= LIR_fge);
}
which I think isn't too bad -- it's very sensible to keep each group of comparisons together, although we could add some static assertions to ensure this. But it would be good to factor the above code out into three methods: isCmpI(), isCmpQ(), isCmpF() because lots of places have things like this:
if (condop >= LIR_eq && condop <= LIR_ge) {
maybe isCmpU() too.
There's also this thing where op^1 gives the inverted comparison (eg. lt -> gt) which would be better hidden within a function cmpInvert().
And we have this which could have a function of its own:
NanoAssert(op >= LIR_fadd && op <= LIR_fdiv);
And jstracer.cpp has this at one point:
if ((op >= LIR_sub && op <= LIR_ush) || // sub, mul, (callh), or, xor, (no
t,) lsh, rsh, ush
(op >= LIR_fsub && op <= LIR_fmod)) { // fsub, fmul, fdiv, fmod
which is worrying because the comments don't match reality and I'm guessing it works out but more by luck than design.
TR doesn't seem to have any range checks that need fixing.
Summary: nanojit: make isCse table-based → nanojit: make opcode range checks safer
![]() |
Assignee | |
Comment 3•15 years ago
|
||
In this patch I:
- Added static assertions for all cases where opcodes have to have
particular values relative to each other. Some existing weaker static
assertions were replaced in the process.
- Added an 'isCse' field to all opcodes in LIRopcode.tbl and changed
isCseOpcode() to use it.
- Inlined isCse() in the one place it was used and removed its definition.
- Added various is*CmpOpcode() functions to encapsulate the range checks.
- Added various invert*Opcode() functions to encapsulate the use of (op ^ 1).
- Used these new functions everywhere suitable, replacing all opcode range
checks that occurred in the wild.
- Introduced the OP_UN() macro for unused opcodes, which is more compact
than the code it replaced.
- Removed a redundant assertion in the the ARM and MIPS backends (in both
bases there is an assertion later in the same function achieving the same
effect).
I checked that the generated code for TM on SunSpider is unchanged.
In theory, you can now rearrange the opcode order arbitrarily and it'll (a)
fail to compile due to static assertion failures, or (b) compile and run
correctly. I haven't tried this yet but I will before landing the patch.
Attachment #427720 -
Flags: review?(stejohns)
![]() |
Assignee | |
Comment 4•15 years ago
|
||
This patch is straightforward except for the bit in TraceRecorder::binary().
The opcode range checking there was kind of bogus, given the inputs to
binary() it was equivalent to "if (op != LIR_fadd)". But because of the
structure of record_JSOP_ADD() those JSVAL_IS_STRING() cases could never
succeed if op==LIR_fadd. So I removed the if and replaced it with
op!=LIR_fadd assertions in the IS_STRING cases.
Attachment #427721 -
Flags: review?(gal)
![]() |
Assignee | |
Updated•15 years ago
|
Attachment #427721 -
Attachment is patch: true
Attachment #427721 -
Attachment mime type: application/octet-stream → text/plain
Comment 5•15 years ago
|
||
Comment on attachment 427721 [details] [diff] [review]
TM patch
Here is the code in question from jstracer.cpp. As njn pints out we never hit those paths for fadd.
if (JSVAL_IS_STRING(l) || JSVAL_IS_STRING(r)) {
LIns* args[] = { stringify(r), stringify(l), cx_ins };
LIns* concat = lir->insCall(&js_ConcatStrings_ci, args);
guard(false, lir->ins_peq0(concat), OOM_EXIT);
set(&l, concat);
return ARECORD_CONTINUE;
}
return InjectStatus(binary(LIR_fadd));
Attachment #427721 -
Flags: review?(gal) → review+
Comment 6•15 years ago
|
||
Comment on attachment 427720 [details] [diff] [review]
NJ patch
"isCses" is declared as "int" -- we should really use C99 types for new code. (For that matter, since the only legal values are -1/0/1, seems like int8_t would be more than adequate.)
Attachment #427720 -
Flags: review?(stejohns) → review+
![]() |
Assignee | |
Comment 7•15 years ago
|
||
I changed isCses to use int8_t.
http://hg.mozilla.org/projects/nanojit-central/rev/a5291bc7b0ce
http://hg.mozilla.org/tracemonkey/rev/c15ecee288b6
http://hg.mozilla.org/tracemonkey/rev/9a50f32c2963
Whiteboard: fixed-in-nanojit, fixed-in-tracemonkey
![]() |
Assignee | |
Comment 8•15 years ago
|
||
(In reply to comment #3)
>
> In theory, you can now rearrange the opcode order arbitrarily and it'll (a)
> fail to compile due to static assertion failures, or (b) compile and run
> correctly. I haven't tried this yet but I will before landing the patch.
BTW, I tried this by sorting the opcodes into alphabetical order, then rearranging them to satisfy the static assertions. After doing that TM trace-tests passed, so that seems like a pretty thorough test.
Updated•15 years ago
|
Whiteboard: fixed-in-nanojit, fixed-in-tracemonkey → fixed-in-nanojit, fixed-in-tracemonkey, fixed-in-tamarin
Comment 9•15 years ago
|
||
Status: ASSIGNED → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
Updated•11 years ago
|
Product: Core → Core Graveyard
You need to log in
before you can comment on or make changes to this bug.
Description
•