diff --git a/js/src/jstracerinlines.h b/js/src/jstracerinlines.h index a799dc2b0f4..43d6bca99d3 100644 --- a/js/src/jstracerinlines.h +++ b/js/src/jstracerinlines.h @@ -66,6 +66,15 @@ record(JSContext* cx, const char* name, void* a, void* b, void* c) native_pointer_to_jsval(c)); } +static inline void +record(JSContext* cx, const char* name, void* a, void* b, void* c, void* d) +{ + js_CallRecorder(cx, name, native_pointer_to_jsval(a), + native_pointer_to_jsval(b), + native_pointer_to_jsval(c), + native_pointer_to_jsval(d)); +} + static inline void record(JSContext* cx, const char* name, void* a, jsval v) { @@ -101,7 +110,7 @@ record(JSContext* cx, const char* name, void* a, jsdouble d) if (!JS_NewDoubleValue(cx, d, &v)) { js_TriggerRecorderError(cx); } else { - record(cx, name, a, v); + record(cx, name, a, &v); } JS_LeaveLocalRootScope(cx); } @@ -117,7 +126,7 @@ record(JSContext* cx, const char* name, void* a, void* b, jsdouble d) if (!JS_NewDoubleValue(cx, d, &v)) { js_TriggerRecorderError(cx); } else { - record(cx, name, a, b, v); + record(cx, name, a, b, &v); } JS_LeaveLocalRootScope(cx); } @@ -133,7 +142,7 @@ record(JSContext* cx, const char* name, void* a, void* b, void* c, jsdouble d) if (!JS_NewDoubleValue(cx, d, &v)) { js_TriggerRecorderError(cx); } else { - record(cx, name, a, b, c, v); + record(cx, name, a, b, c, &v); } JS_LeaveLocalRootScope(cx); } @@ -489,7 +498,7 @@ static inline bool guard_boolean_is_true(JSContext* cx, JSBool& cond) { bool ok = interp_guard_boolean_is_true(cx, cond); - record(cx, "boolean_is_true", &cond, BOOLEAN_TO_JSVAL(ok)); + record(cx, "guard_boolean_is_true", &cond, BOOLEAN_TO_JSVAL(ok)); return ok; } diff --git a/js/src/recorder.js b/js/src/recorder.js index 16265c702c9..0e6b8ef86e0 100644 --- a/js/src/recorder.js +++ b/js/src/recorder.js @@ -53,34 +53,208 @@ track: function(from, to) { this.map[to] = this.map[from]; }, - /* emit an IR instruction */ - emit: function(x, to) { - var x = this.code.push(x); - if (x) - this.map[to] = x; - }, /* register a change in the stack pointer */ setSP: function(sp) { this.SP = sp; }, + /* emit an IR instruction */ + emit: function(x, into) { + return this.code.push(x); + }, + nullary: function(op, into, value) { + print("nullary=" + op + " into=" + into + " value=" + value); + var x = this.emit({ op: op, value: value}); + if (into) + this.map[into] = x; + return x; + }, + unary: function(op, operand, into, value) { + print("unary=" + op + " operand=" + operand + " into=" + into + " value=" + value); + var x = this.emit({ op: op, value: value, operand: operand }); + if (into) + this.map[into] = x; + return x; + }, + binary: function(op, left, right, into, value) { + print("binary=" + op + " left=" + left + " right=" + right + " into=" + into + " value=" + value); + var x = this.emit({ op: op, value: value, left: this.map[left], right: this.map[right] }); + if (into) + this.map[into] = x; + return x; + }, /* create a constant and assign it to v */ generate_constant: function(v, vv) { - this.emit({ op: "generate_constant", value: vv }, v); + this.nullary("generate_constant", v, vv); }, boolean_to_jsval: function(b, v, vv) { - this.emit({ op: "boolean_to_jsval", value: vv, operand: this.map[b] }, v); + this.unary("boolean_to_jsval", b, v, vv); }, string_to_jsval: function(s, v, vv) { - this.emit({ op: "string_to_jsval", value: vv, operand: this.map[s] }, v); - }, + this.unary("string_to_jsval", s, v, vv); + }, object_to_jsval: function(o, v, vv) { - this.emit({ op: "object_to_jsval", value: vv, operand: this.map[o] }, v); + this.unary("object_to_jsval", o, v, vv); }, id_to_jsval: function(id, v, vv) { - this.emit({ op: "id_to_jsval", value: vv, operand: this.map[id] }, v); + this.unary("id_to_jsval", id, v, vv); }, guard_jsdouble_is_int_and_int_fits_in_jsval: function(d, i, vv, g) { - this.emit({ op: "guard_jsdouble_is_int_and_int_fits_in_jsval", value: vv, - operand: this.map[d], state: g }, i); + this.unary("guard_jsdouble_is_int_and_fits_in_jsval", d, i, vv).guard = g; + }, + int_to_jsval: function(i, v, vv) { + this.unary("int_to_jsval", i, v, vv); + }, + new_double_in_rooted_value: function(d, v, vv) { + this.unary("new_double_in_rooted_value", d, v, vv); + }, + guard_int_fits_in_jsval: function(i, g) { + this.unary("guard_int_fits_in_jsval", i).guard = g; + }, + int_to_double: function(i, d, vv) { + this.unary("int_to_double", i, d, vv); + }, + guard_uint_fits_in_jsval: function(u, g) { + this.unary("guard_uint_fits_in_jsval", u).guard = g; + }, + uint_to_jsval: function(u, v, vv) { + this.unary(u, v, vv); + }, + uint_to_double: function(u, d, vv) { + this.unary("uint_to_double", u, d, vv); + }, + guard_jsval_is_int: function(v, g) { + this.unary("guard_jsval_is_int", v).guard = g; + }, + jsval_to_int: function(v, i, vv) { + this.unary("jsval_to_int", v, i, vv); + }, + guard_jsval_is_double: function(v, g) { + this.unary("guard_jsval_is_double", v).guard = g; + }, + jsval_to_double: function(v, d, vv) { + this.unary("jsval_to_double", v, d, vv); + }, + ValueToNumber: function(v, d, vv) { + this.unary("ValueToNumber", v, d, vv); + }, + guard_jsval_is_null: function(v, g) { + this.unary("guard_jsval_is_null", v).guard = g; + }, + ValueToECMAInt32: function(v, i, vv) { + this.unary("ValueToECMAInt32", v, i, vv); + }, + int_to_uint: function(i, u, vv) { + this.unary("int_to_uint", i, u, vv); + }, + ValueToECMAUint32: function(v, u, vv) { + this.unary("ValueToECMAUint32", v, u, vv); + }, + generate_boolean_constant: function(b, vv) { + this.nullary("boolean_constant", b, vv); + }, + guard_jsval_is_boolean: function(v, g) { + this.unary("guard_jsval_is_boolean", v).guard = g; + }, + jsval_to_boolean: function(v, b, vv) { + this.unary("jsval_to_boolean", v, b, vv); + }, + ValueToBoolean: function(v, b, vv) { + this.unary("ValueToBoolean", v, b, vv); + }, + guard_jsval_is_primitive: function(v, g) { + this.unary("guard_jsval_is_primitive", v).guard = g; + }, + jsval_to_object: function(v, obj, vv) { + this.unary("jsval_to_object", v, obj, vv); + }, + guard_obj_is_null: function(obj, g) { + this.unary("guard_obj_is_null", obj).guard = g; + }, + ValueToNonNullObject: function(v, obj, vv) { + this.unary("ValueToNonNullObject", v, obj, vv); + }, + call_obj_default_value: function(obj, hint, v, vv) { + this.binary("obj_to_default_value", obj, hint, v, vv); + }, + dadd: function(a, b, r, vv) { + this.binary("dadd", a, b, r, vv); + }, + dsub: function(a, b, r, vv) { + this.binary("dsub", a, b, r, vv); + }, + dmul: function(a, b, r, vv) { + this.binary("dmul", a, b, r, vv); + }, + ior: function(a, b, r, vv) { + this.binary("ior", a, b, r, vv); + }, + ixor: function(a, b, r, vv) { + this.binary("ixor", a, b, r, vv); + }, + iand: function(a, b, r, vv) { + this.binary("iand", a, b, r, vv); + }, + ilsh: function(a, b, r, vv) { + this.binary("ilsh", a, b, r, vv); + }, + irsh: function(a, b, r, vv) { + this.binary("irsh", a, b, r, vv); + }, + ursh: function(a, b, r, vv) { + this.binary("ursh", a, b, r, vv); + }, + guard_boolean_is_true: function(b, g) { + this.unary("guard_boolean_is_true", b).guard = g; + }, + icmp_lt: function(a, b, r, vv) { + this.binary("icmp_lt", a, b, r, vv); + }, + icmp_le: function(a, b, r, vv) { + this.binary("icmp_le", a, b, r, vv); + }, + icmp_gt: function(a, b, r, vv) { + this.binary("icmp_gt", a, b, r, vv); + }, + icmp_ge: function(a, b, r, vv) { + this.binary("icmp_ge", a, b, r, vv); + }, + dcmp_lt: function(a, b, r, vv) { + this.binary("dcmp_lt", a, b, r, vv); + }, + dcmp_le: function(a, b, r, vv) { + this.binary("dcmp_le", a, b, r, vv); + }, + dcmp_gt: function(a, b, r, vv) { + this.binary("dcmp_gt", a, b, r, vv); + }, + dcmp_ge: function(a, b, r, vv) { + this.binary("dcmp_ge", a, b, r, vv); + }, + dcmp_lt_ifnan: function(a, b, r, vv) { + this.binary("dcmp_lt", a, b, r, vv).if_nan = true; + }, + dcmp_le_ifnan: function(a, b, r, vv) { + this.binary("dcmp_le", a, b, r, vv).if_nan = true; + }, + dcmp_gt_ifnan: function(a, b, r, vv) { + this.binary("dcmp_gt", a, b, r, vv).if_nan = true; + }, + dcmp_ge_ifnan: function(a, b, r, vv) { + this.binary("dcmp_ge", a, b, r, vv).if_nan = true; + }, + generate_int_constant: function(c, vv) { + this.nullary("generate_int_constant", c, vv); + }, + jsval_to_string: function(v, s, vv) { + this.unary("jsval_to_string", v, s, vv); + }, + CompareStrings: function(a, b, r, vv) { + this.binary("CompareStrings", a, b, r, vv); + }, + guard_both_jsvals_are_int: function(a, b, g) { + this.binary("guard_both_jsvals_are_int", a, b).guard = g; + }, + guard_both_jsvals_are_strings: function(a, b, g) { + this.binary("guard_both_jsvals_are_strings", a, b).guard = g; } });