/[jscoverage]/trunk/js/jstracer.cpp
ViewVC logotype

Diff of /trunk/js/jstracer.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 584 by siliconforks, Fri Apr 2 16:18:55 2010 UTC revision 585 by siliconforks, Sun Sep 12 15:13:23 2010 UTC
# Line 7135  Line 7135 
7135                  uint32_t hwcap = aux.a_un.a_val;                  uint32_t hwcap = aux.a_un.a_val;
7136                  if (getenv("ARM_FORCE_HWCAP"))                  if (getenv("ARM_FORCE_HWCAP"))
7137                      hwcap = strtoul(getenv("ARM_FORCE_HWCAP"), NULL, 0);                      hwcap = strtoul(getenv("ARM_FORCE_HWCAP"), NULL, 0);
7138                    else if (getenv("_SBOX_DIR"))
7139                        continue;  // Ignore the rest, if we're running in scratchbox
7140                  // hardcode these values to avoid depending on specific versions                  // hardcode these values to avoid depending on specific versions
7141                  // of the hwcap header, e.g. HWCAP_NEON                  // of the hwcap header, e.g. HWCAP_NEON
7142                  arm_has_thumb = (hwcap & 4) != 0;                  arm_has_thumb = (hwcap & 4) != 0;
# Line 7146  Line 7148 
7148                  const char *plat = (const char*) aux.a_un.a_val;                  const char *plat = (const char*) aux.a_un.a_val;
7149                  if (getenv("ARM_FORCE_PLATFORM"))                  if (getenv("ARM_FORCE_PLATFORM"))
7150                      plat = getenv("ARM_FORCE_PLATFORM");                      plat = getenv("ARM_FORCE_PLATFORM");
7151                    else if (getenv("_SBOX_DIR"))
7152                        continue;  // Ignore the rest, if we're running in scratchbox
7153                  // The platform string has the form "v[0-9][lb]". The "l" or "b" indicate little-                  // The platform string has the form "v[0-9][lb]". The "l" or "b" indicate little-
7154                  // or big-endian variants and the digit indicates the version of the platform.                  // or big-endian variants and the digit indicates the version of the platform.
7155                  // We can only accept ARMv4 and above, but allow anything up to ARMv9 for future                  // We can only accept ARMv4 and above, but allow anything up to ARMv9 for future
# Line 7157  Line 7161 
7161                  {                  {
7162                      arm_arch = plat[1] - '0';                      arm_arch = plat[1] - '0';
7163                  }                  }
                 else  
                 {  
                     // For production code, ignore invalid (or unexpected) platform strings and  
                     // fall back to the default. For debug code, use an assertion to catch this  
                     // when not running in scratchbox.  
                     if (getenv("_SBOX_DIR") == NULL)  
                         JS_ASSERT(false);  
                 }  
7164              }              }
7165          }          }
7166          close (fd);          close (fd);
# Line 8816  Line 8812 
8812          obj_ins = stobj_get_proto(obj_ins);          obj_ins = stobj_get_proto(obj_ins);
8813      }      }
8814    
8815        if (!OBJ_IS_NATIVE(obj))
8816            ABORT_TRACE("non-native object");
8817    
8818      LIns* map_ins = map(obj_ins);      LIns* map_ins = map(obj_ins);
8819    
8820      CHECK_STATUS(guardNativePropertyOp(aobj, map_ins));      CHECK_STATUS(guardNativePropertyOp(aobj, map_ins));
# Line 10354  Line 10353 
10353          }          }
10354          this_ins = box_jsval(vp[1], this_ins);          this_ins = box_jsval(vp[1], this_ins);
10355      }      }
10356        set(&vp[1], this_ins);
10357      lir->insStorei(this_ins, invokevp_ins, 1 * sizeof(jsval));      lir->insStorei(this_ins, invokevp_ins, 1 * sizeof(jsval));
10358    
10359      // Populate argv.      // Populate argv.
# Line 10809  Line 10809 
10809  }  }
10810    
10811  JS_REQUIRES_STACK JSRecordingStatus  JS_REQUIRES_STACK JSRecordingStatus
10812    TraceRecorder::setUpwardTrackedVar(jsval* stackVp, jsval v, LIns* v_ins)
10813    {
10814        JSTraceType stackT = determineSlotType(stackVp);
10815        JSTraceType otherT = getCoercedType(v);
10816    
10817        bool promote = true;
10818    
10819        if (stackT != otherT) {
10820            if (stackT == TT_DOUBLE && otherT == TT_INT32 && isPromoteInt(v_ins))
10821                promote = false;
10822            else
10823                ABORT_TRACE("can't trace this upvar mutation");
10824        }
10825    
10826        set(stackVp, v_ins, promote);
10827    
10828        return JSRS_CONTINUE;
10829    }
10830    
10831    JS_REQUIRES_STACK JSRecordingStatus
10832  TraceRecorder::setCallProp(JSObject *callobj, LIns *callobj_ins, JSScopeProperty *sprop,  TraceRecorder::setCallProp(JSObject *callobj, LIns *callobj_ins, JSScopeProperty *sprop,
10833                             LIns *v_ins, jsval v)                             LIns *v_ins, jsval v)
10834  {  {
# Line 10818  Line 10838 
10838          jsint slot = JSVAL_TO_INT(SPROP_USERID(sprop));          jsint slot = JSVAL_TO_INT(SPROP_USERID(sprop));
10839          if (sprop->setter == SetCallArg) {          if (sprop->setter == SetCallArg) {
10840              jsval *vp2 = &fp->argv[slot];              jsval *vp2 = &fp->argv[slot];
10841              set(vp2, v_ins);              CHECK_STATUS(setUpwardTrackedVar(vp2, v, v_ins));
10842              return JSRS_CONTINUE;              return JSRS_CONTINUE;
10843          }          }
10844          if (sprop->setter == SetCallVar) {          if (sprop->setter == SetCallVar) {
10845              jsval *vp2 = &fp->slots[slot];              jsval *vp2 = &fp->slots[slot];
10846              set(vp2, v_ins);              CHECK_STATUS(setUpwardTrackedVar(vp2, v, v_ins));
10847              return JSRS_CONTINUE;              return JSRS_CONTINUE;
10848          }          }
10849          ABORT_TRACE("can't trace special CallClass setter");          ABORT_TRACE("can't trace special CallClass setter");
# Line 11210  Line 11230 
11230                  // the native stack area. The guard on js_ArgumentClass above ensures the up-to-date                  // the native stack area. The guard on js_ArgumentClass above ensures the up-to-date
11231                  // value has been written back to the native stack area.                  // value has been written back to the native stack area.
11232                  idx_ins = makeNumberInt32(idx_ins);                  idx_ins = makeNumberInt32(idx_ins);
                 if (int_idx >= 0 && int_idx < afp->argc) {  
                     JSTraceType type = getCoercedType(*vp);  
11233    
11234                      // Guard that the argument has the same type on trace as during recording.                  if (int_idx < 0 || int_idx >= afp->argc)
11235                      LIns* typemap_ins;                      ABORT_TRACE("cannot trace arguments with out of range index");
                     if (callDepth == depth) {  
                         // In this case, we are in the same frame where the arguments object was created.  
                         // The entry type map is not necessarily up-to-date, so we capture a new type map  
                         // for this point in the code.  
                         unsigned stackSlots = NativeStackSlots(cx, 0 /* callDepth */);  
                         if (stackSlots * sizeof(JSTraceType) > LirBuffer::MAX_SKIP_PAYLOAD_SZB)  
                             ABORT_TRACE("|arguments| requires saving too much stack");  
                         JSTraceType* typemap = new (*traceMonitor->dataAlloc) JSTraceType[stackSlots];  
                         DetermineTypesVisitor detVisitor(*this, typemap);  
                         VisitStackSlots(detVisitor, cx, 0);  
                         typemap_ins = INS_CONSTPTR(typemap + 2 /* callee, this */);  
                     } else {  
                         // In this case, we are in a deeper frame from where the arguments object was  
                         // created. The type map at the point of the call out from the creation frame  
                         // is accurate.  
                         // Note: this relies on the assumption that we abort on setting an element of  
                         // an arguments object in any deeper frame.  
                         LIns* fip_ins = lir->insLoad(LIR_ldp, lirbuf->rp, (callDepth-depth)*sizeof(FrameInfo*));  
                         typemap_ins = lir->ins2(LIR_add, fip_ins, INS_CONST(sizeof(FrameInfo) + 2/*callee,this*/ * sizeof(JSTraceType)));  
                     }  
11236    
11237                      LIns* typep_ins = lir->ins2(LIR_piadd, typemap_ins,                  guard(true,
11238                                                  lir->ins_u2p(lir->ins2(LIR_mul,                        addName(lir->ins2(LIR_ge, idx_ins, INS_CONST(0)),
11239                                                                         idx_ins,                                "guard(index >= 0)"),
11240                                                                         INS_CONST(sizeof(JSTraceType)))));                        MISMATCH_EXIT);
11241                      LIns* type_ins = lir->insLoad(LIR_ldcb, typep_ins, 0);                  guard(true,
11242                      guard(true,                        addName(lir->ins2(LIR_lt, idx_ins, INS_CONST(afp->argc)),
11243                            addName(lir->ins2(LIR_eq, type_ins, lir->insImm(type)),                                "guard(index < argc)"),
11244                                    "guard(type-stable upvar)"),                        MISMATCH_EXIT);
11245                            BRANCH_EXIT);  
11246                    JSTraceType type = getCoercedType(*vp);
11247                      // Read the value out of the native stack area.  
11248                      guard(true, lir->ins2(LIR_ult, idx_ins, INS_CONST(afp->argc)),                  // Guard that the argument has the same type on trace as during recording.
11249                            snapshot(BRANCH_EXIT));                  LIns* typemap_ins;
11250                      size_t stackOffset = -treeInfo->nativeStackBase + nativeStackOffset(&afp->argv[0]);                  if (depth == 0) {
11251                      LIns* args_addr_ins = lir->ins2(LIR_piadd, lirbuf->sp, INS_CONSTWORD(stackOffset));                      // In this case, we are in the same frame where the arguments object was created.
11252                      LIns* argi_addr_ins = lir->ins2(LIR_piadd,                      // The entry type map is not necessarily up-to-date, so we capture a new type map
11253                                                      args_addr_ins,                      // for this point in the code.
11254                                                      lir->ins_u2p(lir->ins2(LIR_mul,                      unsigned stackSlots = NativeStackSlots(cx, 0 /* callDepth */);
11255                                                                             idx_ins,                      if (stackSlots * sizeof(JSTraceType) > LirBuffer::MAX_SKIP_PAYLOAD_SZB)
11256                                                                             INS_CONST(sizeof(double)))));                          ABORT_TRACE("|arguments| requires saving too much stack");
11257                      v_ins = stackLoad(argi_addr_ins, type);                      JSTraceType* typemap = new (*traceMonitor->dataAlloc) JSTraceType[stackSlots];
11258                        DetermineTypesVisitor detVisitor(*this, typemap);
11259                        VisitStackSlots(detVisitor, cx, 0);
11260                        typemap_ins = INS_CONSTPTR(typemap + 2 /* callee, this */);
11261                  } else {                  } else {
11262                      guard(false, lir->ins2(LIR_ult, idx_ins, INS_CONST(afp->argc)),                      // In this case, we are in a deeper frame from where the arguments object was
11263                            snapshot(BRANCH_EXIT));                      // created. The type map at the point of the call out from the creation frame
11264                      v_ins = INS_VOID();                      // is accurate.
11265                        // Note: this relies on the assumption that we abort on setting an element of
11266                        // an arguments object in any deeper frame.
11267                        LIns* fip_ins = lir->insLoad(LIR_ldp, lirbuf->rp, (callDepth-depth)*sizeof(FrameInfo*));
11268                        typemap_ins = lir->ins2(LIR_add, fip_ins, INS_CONST(sizeof(FrameInfo) + 2/*callee,this*/ * sizeof(JSTraceType)));
11269                  }                  }
11270    
11271                    LIns* typep_ins = lir->ins2(LIR_piadd, typemap_ins,
11272                                                lir->ins_u2p(lir->ins2(LIR_mul,
11273                                                                       idx_ins,
11274                                                                       INS_CONST(sizeof(JSTraceType)))));
11275                    LIns* type_ins = lir->insLoad(LIR_ldcb, typep_ins, 0);
11276                    guard(true,
11277                          addName(lir->ins2(LIR_eq, type_ins, lir->insImm(type)),
11278                                  "guard(type-stable upvar)"),
11279                          BRANCH_EXIT);
11280    
11281                    // Read the value out of the native stack area.
11282                    guard(true, lir->ins2(LIR_ult, idx_ins, INS_CONST(afp->argc)),
11283                          snapshot(BRANCH_EXIT));
11284                    size_t stackOffset = -treeInfo->nativeStackBase + nativeStackOffset(&afp->argv[0]);
11285                    LIns* args_addr_ins = lir->ins2(LIR_piadd, lirbuf->sp, INS_CONSTWORD(stackOffset));
11286                    LIns* argi_addr_ins = lir->ins2(LIR_piadd,
11287                                                    args_addr_ins,
11288                                                    lir->ins_u2p(lir->ins2(LIR_mul,
11289                                                                           idx_ins,
11290                                                                           INS_CONST(sizeof(double)))));
11291                    v_ins = stackLoad(argi_addr_ins, type);
11292              }              }
11293              JS_ASSERT(v_ins);              JS_ASSERT(v_ins);
11294              set(&lval, v_ins);              set(&lval, v_ins);
# Line 11421  Line 11448 
11448      if (JS_InstanceOf(cx, obj, &js_ArgumentsClass, NULL))      if (JS_InstanceOf(cx, obj, &js_ArgumentsClass, NULL))
11449          ABORT_TRACE("can't trace setting elements of the |arguments| object");          ABORT_TRACE("can't trace setting elements of the |arguments| object");
11450    
11451        if (obj == globalObj)
11452            ABORT_TRACE("can't trace setting elements on the global object");
11453    
11454      if (!JSVAL_IS_INT(idx)) {      if (!JSVAL_IS_INT(idx)) {
11455          if (!JSVAL_IS_PRIMITIVE(idx))          if (!JSVAL_IS_PRIMITIVE(idx))
11456              ABORT_TRACE("non-primitive index");              ABORT_TRACE("non-primitive index");
# Line 12798  Line 12828 
12828      // Find the target object.      // Find the target object.
12829      JSAtom *atom = atoms[GET_INDEX(cx->fp->regs->pc)];      JSAtom *atom = atoms[GET_INDEX(cx->fp->regs->pc)];
12830      jsid id = ATOM_TO_JSID(atom);      jsid id = ATOM_TO_JSID(atom);
12831        JSContext *localCx = cx;
12832      JSObject *obj2 = js_FindIdentifierBase(cx, fp->scopeChain, id);      JSObject *obj2 = js_FindIdentifierBase(cx, fp->scopeChain, id);
12833        if (!obj2)
12834            ABORT_TRACE_ERROR("js_FindIdentifierBase failed");
12835        if (!TRACE_RECORDER(localCx))
12836            return JSRS_STOP;
12837      if (obj2 != globalObj && STOBJ_GET_CLASS(obj2) != &js_CallClass)      if (obj2 != globalObj && STOBJ_GET_CLASS(obj2) != &js_CallClass)
12838          ABORT_TRACE("BINDNAME on non-global, non-call object");          ABORT_TRACE("BINDNAME on non-global, non-call object");
12839    
# Line 13149  Line 13184 
13184      JSStackFrame* fp = cx->fp;      JSStackFrame* fp = cx->fp;
13185      if (!(fp->fun->flags & JSFUN_HEAVYWEIGHT)) {      if (!(fp->fun->flags & JSFUN_HEAVYWEIGHT)) {
13186          uintN slot = GET_ARGNO(fp->regs->pc);          uintN slot = GET_ARGNO(fp->regs->pc);
13187          if (slot < fp->argc)          if (slot >= fp->argc)
13188              stack(0, get(&cx->fp->argv[slot]));              ABORT_TRACE("can't trace out-of-range arguments");
13189          else          stack(0, get(&cx->fp->argv[slot]));
             stack(0, INS_VOID());  
13190          return JSRS_CONTINUE;          return JSRS_CONTINUE;
13191      }      }
13192      ABORT_TRACE("can't trace JSOP_ARGSUB hard case");      ABORT_TRACE("can't trace JSOP_ARGSUB hard case");

Legend:
Removed from v.584  
changed lines
  Added in v.585

  ViewVC Help
Powered by ViewVC 1.1.24