Bug 1507066 part 3 - Move the bytecodeTypeMap hint to TypeScript. r=tcampbell
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 25 Jan 2019 07:17:18 +0000
changeset 515402 ddf227b9fa75462ad55cd4cac39e3d81fda7c491
parent 515401 ec1aa436aeff3fe194c7077dcbb18950b0b3c5d0
child 515403 686e61adb6281c0a2771cbcbab538a577ebfd14d
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1507066
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1507066 part 3 - Move the bytecodeTypeMap hint to TypeScript. r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D17477
js/src/vm/TypeInference-inl.h
js/src/vm/TypeInference.cpp
js/src/vm/TypeInference.h
--- a/js/src/vm/TypeInference-inl.h
+++ b/js/src/vm/TypeInference-inl.h
@@ -690,17 +690,17 @@ template <typename TYPESET>
 /* static */ inline StackTypeSet* TypeScript::BytecodeTypes(JSScript* script,
                                                             jsbytecode* pc) {
   MOZ_ASSERT(CurrentThreadCanAccessZone(script->zone()));
   AutoSweepTypeScript sweep(script);
   TypeScript* types = script->types(sweep);
   if (!types) {
     return nullptr;
   }
-  uint32_t* hint = types->bytecodeTypeMap() + script->numBytecodeTypeSets();
+  uint32_t* hint = types->bytecodeTypeMapHint();
   return BytecodeTypes(script, pc, types->bytecodeTypeMap(), hint,
                        types->typeArray());
 }
 
 /* static */ inline void TypeScript::Monitor(JSContext* cx, JSScript* script,
                                              jsbytecode* pc,
                                              const js::Value& rval) {
   TypeMonitorResult(cx, script, pc, rval);
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -3509,20 +3509,16 @@ static void FillBytecodeTypeMap(JSScript
     if (CodeSpec[op].format & JOF_TYPESET) {
       bytecodeMap[added++] = script->pcToOffset(pc);
       if (added == script->numBytecodeTypeSets()) {
         break;
       }
     }
   }
   MOZ_ASSERT(added == script->numBytecodeTypeSets());
-
-  // The last entry in the last index found, and is used to avoid binary
-  // searches for the sought entry when queries are in linear order.
-  bytecodeMap[script->numBytecodeTypeSets()] = 0;
 }
 
 void js::TypeMonitorResult(JSContext* cx, JSScript* script, jsbytecode* pc,
                            TypeSet::Type type) {
   cx->check(script, type);
 
   AutoEnterAnalysis enter(cx);
 
@@ -3585,17 +3581,19 @@ static size_t NumTypeSets(JSScript* scri
   static_assert(JSFunction::NArgsBits == 16,
                 "JSFunction nargs should have safe range to avoid overflow");
 
   return num;
 }
 
 TypeScript::TypeScript(JSScript* script, ICScriptPtr&& icScript,
                        uint32_t numTypeSets)
-    : icScript_(std::move(icScript)), numTypeSets_(numTypeSets) {
+    : icScript_(std::move(icScript)),
+      numTypeSets_(numTypeSets),
+      bytecodeTypeMapHint_(0) {
   StackTypeSet* array = typeArray();
   for (unsigned i = 0; i < numTypeSets; i++) {
     new (&array[i]) StackTypeSet();
   }
 
   FillBytecodeTypeMap(script, bytecodeTypeMap());
 }
 
@@ -3610,20 +3608,17 @@ bool JSScript::makeTypes(JSContext* cx) 
     return false;
   }
 
   // We need to call prepareForDestruction on ICScript before we |delete| it.
   auto prepareForDestruction = mozilla::MakeScopeExit(
       [&] { icScript->prepareForDestruction(cx->zone()); });
 
   size_t numTypeSets = NumTypeSets(this);
-
-  // Note: There is an extra entry in the bytecode type map for the search
-  // hint, see FillBytecodeTypeMap.
-  size_t bytecodeTypeMapEntries = numBytecodeTypeSets() + 1;
+  size_t bytecodeTypeMapEntries = numBytecodeTypeSets();
 
   // Calculate allocation size. This cannot overflow, see comment in
   // NumTypeSets.
   static_assert(sizeof(TypeScript) ==
                     sizeof(StackTypeSet) + offsetof(TypeScript, typeArray_),
                 "typeArray_ must be last member of TypeScript");
   size_t allocSize =
       (offsetof(TypeScript, typeArray_) + numTypeSets * sizeof(StackTypeSet) +
--- a/js/src/vm/TypeInference.h
+++ b/js/src/vm/TypeInference.h
@@ -211,32 +211,38 @@ class TypeScript {
   // ICScript and TypeScript have the same lifetimes, so we store a pointer to
   // ICScript here to not increase sizeof(JSScript).
   using ICScriptPtr = js::UniquePtr<js::jit::ICScript>;
   ICScriptPtr icScript_;
 
   // Number of TypeSets in typeArray_.
   uint32_t numTypeSets_;
 
+  // This field is used to avoid binary searches for the sought entry when
+  // bytecode map queries are in linear order.
+  uint32_t bytecodeTypeMapHint_;
+
   // Variable-size array. This is followed by the bytecode type map.
   StackTypeSet typeArray_[1];
 
  public:
   TypeScript(JSScript* script, ICScriptPtr&& icScript, uint32_t numTypeSets);
 
   RecompileInfoVector& inlinedCompilations() { return inlinedCompilations_; }
   MOZ_MUST_USE bool addInlinedCompilation(RecompileInfo info) {
     if (!inlinedCompilations_.empty() && inlinedCompilations_.back() == info) {
       return true;
     }
     return inlinedCompilations_.append(info);
   }
 
   uint32_t numTypeSets() const { return numTypeSets_; }
 
+  uint32_t* bytecodeTypeMapHint() { return &bytecodeTypeMapHint_; }
+
   jit::ICScript* icScript() const {
     MOZ_ASSERT(icScript_);
     return icScript_.get();
   }
 
   /* Array of type sets for variables and JOF_TYPESET ops. */
   StackTypeSet* typeArray() const {
     // Ensure typeArray_ is the last data member of TypeScript.