Bug 1642593 - Support GuardToClass in CacheIR. r=jandem
authorTom Schuster <evilpies@gmail.com>
Wed, 03 Jun 2020 17:23:38 +0000
changeset 533737 aa20bf181fd0f0dcb9d7f31acadabd69517ff7b3
parent 533736 ca5509801aab67bed7c465bc0f22f40d130cc23a
child 533738 ce2ec4204fe8517bf7725d162ba55b6d3297966c
push id37477
push userdluca@mozilla.com
push dateThu, 04 Jun 2020 04:19:27 +0000
treeherdermozilla-central@6fd265574f27 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1642593
milestone79.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 1642593 - Support GuardToClass in CacheIR. r=jandem Differential Revision: https://phabricator.services.mozilla.com/D77792
js/src/jit/CacheIR.cpp
js/src/jit/CacheIR.h
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -5172,16 +5172,53 @@ AttachDecision CallIRGenerator::tryAttac
   // returns a boolean.
   writer.returnFromIC();
   cacheIRStubKind_ = BaselineCacheIRStubKind::Regular;
 
   trackAttached("IsConstructor");
   return AttachDecision::Attach;
 }
 
+AttachDecision CallIRGenerator::tryAttachGuardToClass(HandleFunction callee,
+                                                      InlinableNative native) {
+  // Need a single object argument.
+  if (argc_ != 1 || !args_[0].isObject()) {
+    return AttachDecision::NoAction;
+  }
+
+  // Class must match.
+  const JSClass* clasp = InlinableNativeGuardToClass(native);
+  if (args_[0].toObject().getClass() != clasp) {
+    return AttachDecision::NoAction;
+  }
+
+  // Initialize the input operand.
+  Int32OperandId argcId(writer.setInputOperandId(0));
+
+  // Guard callee is the 'GuardToXXX' native function.
+  emitNativeCalleeGuard(callee);
+
+  // Guard that the argument is an object.
+  ValOperandId argId = writer.loadArgumentFixedSlot(ArgumentKind::Arg0, argc_);
+  ObjOperandId objId = writer.guardToObject(argId);
+
+  // Guard that the object has the correct class.
+  writer.guardAnyClass(objId, clasp);
+
+  // Return the object.
+  writer.loadObjectResult(objId);
+
+  // Monitor the returned object.
+  writer.typeMonitorResult();
+  cacheIRStubKind_ = BaselineCacheIRStubKind::Monitored;
+
+  trackAttached("GuardToClass");
+  return AttachDecision::Attach;
+}
+
 AttachDecision CallIRGenerator::tryAttachStringChar(HandleFunction callee,
                                                     StringChar kind) {
   // Need one argument.
   if (argc_ != 1) {
     return AttachDecision::NoAction;
   }
 
   if (!CanAttachStringChar(thisval_, args_[0], kind)) {
@@ -5590,40 +5627,57 @@ AttachDecision CallIRGenerator::tryAttac
   }
 
   if (!callee->hasJitInfo() ||
       callee->jitInfo()->type() != JSJitInfo::InlinableNative) {
     return AttachDecision::NoAction;
   }
 
   // Check for special-cased native functions.
-  switch (callee->jitInfo()->inlinableNative) {
+  switch (InlinableNative native = callee->jitInfo()->inlinableNative) {
     // Array natives.
     case InlinableNative::ArrayPush:
       return tryAttachArrayPush(callee);
     case InlinableNative::ArrayJoin:
       return tryAttachArrayJoin(callee);
     case InlinableNative::ArrayIsArray:
       return tryAttachArrayIsArray(callee);
 
+    // Intl natives.
+    case InlinableNative::IntlGuardToCollator:
+    case InlinableNative::IntlGuardToDateTimeFormat:
+    case InlinableNative::IntlGuardToDisplayNames:
+    case InlinableNative::IntlGuardToListFormat:
+    case InlinableNative::IntlGuardToNumberFormat:
+    case InlinableNative::IntlGuardToPluralRules:
+    case InlinableNative::IntlGuardToRelativeTimeFormat:
+      return tryAttachGuardToClass(callee, native);
+
     // Intrinsics.
     case InlinableNative::IntrinsicIsSuspendedGenerator:
       return tryAttachIsSuspendedGenerator(callee);
     case InlinableNative::IntrinsicToString:
       return tryAttachToString(callee);
     case InlinableNative::IntrinsicToObject:
       return tryAttachToObject(callee);
     case InlinableNative::IntrinsicToInteger:
       return tryAttachToInteger(callee);
     case InlinableNative::IntrinsicIsObject:
       return tryAttachIsObject(callee);
     case InlinableNative::IntrinsicIsCallable:
       return tryAttachIsCallable(callee);
     case InlinableNative::IntrinsicIsConstructor:
       return tryAttachIsConstructor(callee);
+    case InlinableNative::IntrinsicGuardToArrayIterator:
+    case InlinableNative::IntrinsicGuardToMapIterator:
+    case InlinableNative::IntrinsicGuardToSetIterator:
+    case InlinableNative::IntrinsicGuardToStringIterator:
+    case InlinableNative::IntrinsicGuardToRegExpStringIterator:
+    case InlinableNative::IntrinsicGuardToWrapForValidIterator:
+      return tryAttachGuardToClass(callee, native);
 
     // String natives.
     case InlinableNative::StringCharCodeAt:
       return tryAttachStringCharCodeAt(callee);
     case InlinableNative::StringCharAt:
       return tryAttachStringCharAt(callee);
 
     // Math natives.
@@ -5671,16 +5725,32 @@ AttachDecision CallIRGenerator::tryAttac
       return tryAttachMathFunction(callee, UnaryMathFunction::ACosH);
     case InlinableNative::MathASinH:
       return tryAttachMathFunction(callee, UnaryMathFunction::ASinH);
     case InlinableNative::MathATanH:
       return tryAttachMathFunction(callee, UnaryMathFunction::ATanH);
     case InlinableNative::MathCbrt:
       return tryAttachMathFunction(callee, UnaryMathFunction::Cbrt);
 
+    // Map intrinsics.
+    case InlinableNative::IntrinsicGuardToMapObject:
+      return tryAttachGuardToClass(callee, native);
+
+    // Set intrinsics.
+    case InlinableNative::IntrinsicGuardToSetObject:
+      return tryAttachGuardToClass(callee, native);
+
+    // ArrayBuffer intrinsics.
+    case InlinableNative::IntrinsicGuardToArrayBuffer:
+      return tryAttachGuardToClass(callee, native);
+
+    // SharedArrayBuffer intrinsics.
+    case InlinableNative::IntrinsicGuardToSharedArrayBuffer:
+      return tryAttachGuardToClass(callee, native);
+
     default:
       return AttachDecision::NoAction;
   }
 }
 
 // Remember the template object associated with any script being called
 // as a constructor, for later use during Ion compilation.
 bool CallIRGenerator::getTemplateObjectForScripted(HandleFunction calleeFunc,
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -21,16 +21,17 @@
 #include "jit/Simulator.h"
 #include "vm/Iteration.h"
 #include "vm/Shape.h"
 
 namespace js {
 namespace jit {
 
 enum class BaselineCacheIRStubKind;
+enum class InlinableNative : uint16_t;
 
 // [SMDOC] CacheIR
 //
 // CacheIR is an (extremely simple) linear IR language for inline caches.
 // From this IR, we can generate machine code for Baseline or Ion IC stubs.
 //
 // IRWriter
 // --------
@@ -1523,16 +1524,18 @@ class MOZ_RAII CallIRGenerator : public 
   AttachDecision tryAttachArrayIsArray(HandleFunction callee);
   AttachDecision tryAttachIsSuspendedGenerator(HandleFunction callee);
   AttachDecision tryAttachToString(HandleFunction callee);
   AttachDecision tryAttachToObject(HandleFunction callee);
   AttachDecision tryAttachToInteger(HandleFunction callee);
   AttachDecision tryAttachIsObject(HandleFunction callee);
   AttachDecision tryAttachIsCallable(HandleFunction callee);
   AttachDecision tryAttachIsConstructor(HandleFunction callee);
+  AttachDecision tryAttachGuardToClass(HandleFunction callee,
+                                       InlinableNative native);
   AttachDecision tryAttachStringChar(HandleFunction callee, StringChar kind);
   AttachDecision tryAttachStringCharCodeAt(HandleFunction callee);
   AttachDecision tryAttachStringCharAt(HandleFunction callee);
   AttachDecision tryAttachMathAbs(HandleFunction callee);
   AttachDecision tryAttachMathFloor(HandleFunction callee);
   AttachDecision tryAttachMathCeil(HandleFunction callee);
   AttachDecision tryAttachMathRound(HandleFunction callee);
   AttachDecision tryAttachMathSqrt(HandleFunction callee);