JSOP_ADD over strings
authorshaver@mozilla.org
Tue, 29 Jul 2008 07:53:31 -0700
changeset 17872 624a5f42008b63d7bf10f5a791eb093bbba3580d
parent 17871 baa9cc8969fbfedfec31c2643a266fd7c372fc99
child 17873 77a50b8cf504f980dcc20cdd47a7ddfb0a7e592e
child 17876 21de271f5a7b21f0f37df367fef6212b7af99b51
push id1452
push usershaver@mozilla.com
push dateFri, 22 Aug 2008 00:08:22 +0000
treeherderautoland@d13bb0868596 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.1a1pre
JSOP_ADD over strings
js/src/builtins.tbl
js/src/jsbuiltins.cpp
js/src/jstracer.cpp
js/src/trace-test.js
--- a/js/src/builtins.tbl
+++ b/js/src/builtins.tbl
@@ -45,8 +45,9 @@ BUILTIN1(doubleToInt32,         F,      
 BUILTIN1(doubleToUint32,        F,      LO,     int32,     jsdouble,                           1, 1)
 BUILTIN1(Math_sin,              F,      F,      jsdouble,  jsdouble,                           1, 1)
 BUILTIN1(Math_cos,              F,      F,      jsdouble,  jsdouble,                           1, 1)
 BUILTIN2(Math_pow,              F,  F,  F,      jsdouble,  jsdouble, jsdouble,                 1, 1)
 BUILTIN1(Math_sqrt,             F,      F,      jsdouble,  jsdouble,                           1, 1)
 BUILTIN4(Array_dense_setelem,   LO, LO, LO, LO, LO, bool, JSContext*, JSObject*, jsint, jsval, 1, 1)
 BUILTIN4(String_p_substring,    LO, LO, LO, LO, LO, JSString*, JSContext*, JSString*, jsint, jsint, 1, 1)
 BUILTIN3(String_p_substring_1,  LO, LO, LO, LO, JSString*, JSContext*, JSString*, jsint, 1, 1)
+BUILTIN3(ConcatStrings,         LO, LO, LO, LO, JSString*, JSContext*, JSString*, JSString*, 1, 1)
--- a/js/src/jsbuiltins.cpp
+++ b/js/src/jsbuiltins.cpp
@@ -181,16 +181,24 @@ builtin_String_p_substring(JSContext *cx
 JSString* FASTCALL
 builtin_String_p_substring_1(JSContext *cx, JSString *str, jsint begin)
 {
     jsint end = JSSTRING_LENGTH(str);
     JS_ASSERT(end >= begin);
     return js_NewDependentString(cx, str, (size_t)begin, (size_t)(end - begin));
 }
 
+JSString* FASTCALL
+builtin_ConcatStrings(JSContext *cx, JSString* left, JSString* right)
+{
+    /* XXX check for string freelist space */
+    /* XXX just make js_ConcatStrings FASTCALL? */
+    return js_ConcatStrings(cx, left, right);
+}
+
 #define LO ARGSIZE_LO
 #define F  ARGSIZE_F
 #define Q  ARGSIZE_Q
 
 #ifdef DEBUG
 #define NAME(op) ,#op
 #else
 #define NAME(op)
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -2244,16 +2244,25 @@ bool TraceRecorder::record_JSOP_RSH()
     return binary(LIR_rsh);
 }
 bool TraceRecorder::record_JSOP_URSH()
 {
     return binary(LIR_ush);
 }
 bool TraceRecorder::record_JSOP_ADD()
 {
+    jsval& r = stackval(-1);
+    jsval& l = stackval(-2);
+    if (JSVAL_IS_STRING(l) && JSVAL_IS_STRING(r)) {
+        LIns* args[] = { get(&r), get(&l), cx_ins };
+        LIns* concat = lir->insCall(F_ConcatStrings, args);
+        guard(false, lir->ins_eq0(concat));
+        set(&l, concat);
+        return true;
+    }
     return binary(LIR_fadd);
 }
 bool TraceRecorder::record_JSOP_SUB()
 {
     return binary(LIR_fsub);
 }
 bool TraceRecorder::record_JSOP_MUL()
 {
--- a/js/src/trace-test.js
+++ b/js/src/trace-test.js
@@ -304,18 +304,18 @@ function unboxint() {
 }
 test("unboxint", unboxint(), "8");
 
 function strings()
 {
   var a = [], b = -1;
   var s = "abcdefghij";
   for (var i = 0; i < 10; i++) {
-    a[i] = s.substring(i, i+1);
+    a[i] = s.substring(i, i+1) + s.substring(i, i+1);
     b = s.length;
   }
   return a.toString() + b;
 }
-test("strings", strings(), "a,b,c,d,e,f,g,h,i,j10");
+test("strings", strings(), "aa,bb,cc,dd,ee,ff,gg,hh,ii,jj10");
 
 /* Keep these at the end so that we can see the summary after the trace-debug spew. */
 print("pass:", passes.length ? passes.join(",") : "<none>");
 print("FAIL:", fails.length ? fails.join(",") : "<none>");