_Z14ImportCallbackPvPKcS1_PPcS3_Pm:
   26|    105|                     char** found_here, char **buf, size_t *buflen) {
   27|       |  // Don't load file and mark it as failure.
   28|    105|  *buf = NULL;
   29|    105|  *buflen = 0;
   30|    105|  return 1;
   31|    105|}
_Z20ConvertJsonnetToJsonRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE:
   33|  9.27k|std::string ConvertJsonnetToJson(const std::string& jsonnet) {
   34|  9.27k|  JsonnetVm* jvm = jsonnet_make();
   35|  9.27k|  jsonnet_import_callback(jvm, ImportCallback, jvm);
   36|  9.27k|  int error = 0;
   37|  9.27k|  char* res =
   38|  9.27k|      jsonnet_evaluate_snippet_stream(jvm, /*filename=*/"", jsonnet.c_str(), &error);
   39|       |
   40|  9.27k|  std::string json;
   41|  9.27k|  if (error == 0 && res != nullptr) {
  ------------------
  |  Branch (41:7): [True: 717, False: 8.55k]
  |  Branch (41:21): [True: 717, False: 0]
  ------------------
   42|    717|    json = res;
   43|    717|  }
   44|       |
   45|  9.27k|  if (res) {
  ------------------
  |  Branch (45:7): [True: 9.27k, False: 0]
  ------------------
   46|  9.27k|    jsonnet_realloc(jvm, res, 0);
   47|  9.27k|  }
   48|  9.27k|  jsonnet_destroy(jvm);
   49|  9.27k|  return json;
   50|  9.27k|}
LLVMFuzzerTestOneInput:
   52|  9.27k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   53|  9.27k|  std::string fuzz_jsonnet(reinterpret_cast<const char*>(data), size);
   54|  9.27k|  ConvertJsonnetToJson(fuzz_jsonnet);
   55|  9.27k|  return 0;
   56|  9.27k|}

libjsonnet.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1014|      2|{
 1015|      2|    std::map<BinaryOp, int> r;
 1016|       |
 1017|      2|    r[BOP_MULT] = 5;
 1018|      2|    r[BOP_DIV] = 5;
 1019|      2|    r[BOP_PERCENT] = 5;
 1020|       |
 1021|      2|    r[BOP_PLUS] = 6;
 1022|      2|    r[BOP_MINUS] = 6;
 1023|       |
 1024|      2|    r[BOP_SHIFT_L] = 7;
 1025|      2|    r[BOP_SHIFT_R] = 7;
 1026|       |
 1027|      2|    r[BOP_GREATER] = 8;
 1028|      2|    r[BOP_GREATER_EQ] = 8;
 1029|      2|    r[BOP_LESS] = 8;
 1030|      2|    r[BOP_LESS_EQ] = 8;
 1031|      2|    r[BOP_IN] = 8;
 1032|       |
 1033|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1034|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1035|       |
 1036|      2|    r[BOP_BITWISE_AND] = 10;
 1037|       |
 1038|      2|    r[BOP_BITWISE_XOR] = 11;
 1039|       |
 1040|      2|    r[BOP_BITWISE_OR] = 12;
 1041|       |
 1042|      2|    r[BOP_AND] = 13;
 1043|       |
 1044|      2|    r[BOP_OR] = 14;
 1045|       |
 1046|      2|    return r;
 1047|      2|}
libjsonnet.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1050|      2|{
 1051|      2|    std::map<std::string, UnaryOp> r;
 1052|      2|    r["!"] = UOP_NOT;
 1053|      2|    r["~"] = UOP_BITWISE_NOT;
 1054|      2|    r["+"] = UOP_PLUS;
 1055|      2|    r["-"] = UOP_MINUS;
 1056|      2|    return r;
 1057|      2|}
libjsonnet.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1060|      2|{
 1061|      2|    std::map<std::string, BinaryOp> r;
 1062|       |
 1063|      2|    r["*"] = BOP_MULT;
 1064|      2|    r["/"] = BOP_DIV;
 1065|      2|    r["%"] = BOP_PERCENT;
 1066|       |
 1067|      2|    r["+"] = BOP_PLUS;
 1068|      2|    r["-"] = BOP_MINUS;
 1069|       |
 1070|      2|    r["<<"] = BOP_SHIFT_L;
 1071|      2|    r[">>"] = BOP_SHIFT_R;
 1072|       |
 1073|      2|    r[">"] = BOP_GREATER;
 1074|      2|    r[">="] = BOP_GREATER_EQ;
 1075|      2|    r["<"] = BOP_LESS;
 1076|      2|    r["<="] = BOP_LESS_EQ;
 1077|      2|    r["in"] = BOP_IN;
 1078|       |
 1079|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1080|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1081|       |
 1082|      2|    r["&"] = BOP_BITWISE_AND;
 1083|      2|    r["^"] = BOP_BITWISE_XOR;
 1084|      2|    r["|"] = BOP_BITWISE_OR;
 1085|       |
 1086|      2|    r["&&"] = BOP_AND;
 1087|      2|    r["||"] = BOP_OR;
 1088|      2|    return r;
 1089|      2|}
_ZN7jsonnet8internal9AllocatorD2Ev:
  991|  9.27k|    {
  992|   135M|        for (auto x : allocated) {
  ------------------
  |  Branch (992:21): [True: 135M, False: 9.27k]
  ------------------
  993|   135M|            delete x;
  994|   135M|        }
  995|  9.27k|        allocated.clear();
  996|  3.16M|        for (const auto &x : internedIdentifiers) {
  ------------------
  |  Branch (996:28): [True: 3.16M, False: 9.27k]
  ------------------
  997|  3.16M|            delete x.second;
  998|  3.16M|        }
  999|  9.27k|        internedIdentifiers.clear();
 1000|  9.27k|    }
_ZN7jsonnet8internal10IdentifierC2ERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEE:
  111|  3.80M|    Identifier(const UString &name) : name(name) {}
_ZN7jsonnet8internal3ASTC2ERKNS0_13LocationRangeENS0_7ASTTypeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEE:
  131|   117M|    {
  132|   117M|    }
_ZN7jsonnet8internal3ASTD2Ev:
  133|   135M|    virtual ~AST(void) {}
_ZN7jsonnet8internal8ArgParamC2ERKNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEEPKNS0_10IdentifierES9_:
  157|   784k|    {
  158|   784k|    }
_ZN7jsonnet8internal8ArgParamC2EPNS0_3ASTERKNSt3__16vectorINS0_13FodderElementENS4_9allocatorIS6_EEEE:
  162|  8.68M|    {
  163|  8.68M|    }
_ZN7jsonnet8internal8ArgParamC2ERKNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEEPKNS0_10IdentifierES9_PNS0_3ASTES9_:
  168|  17.0M|    {
  169|  17.0M|    }
_ZN7jsonnet8internal17ComprehensionSpecC2ENS1_4KindERKNSt3__16vectorINS0_13FodderElementENS3_9allocatorIS5_EEEESA_PKNS0_10IdentifierESA_PNS0_3ASTE:
  191|   842k|    {
  192|   842k|    }
_ZN7jsonnet8internal5ApplyC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_RKNS6_INS0_8ArgParamENS8_ISF_EEEEbSC_SC_b:
  215|  12.0M|    {
  216|  12.0M|    }
_ZN7jsonnet8internal10ApplyBraceC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESE_:
  225|  83.1k|    {
  226|  83.1k|    }
_ZN7jsonnet8internal5Array7ElementC2EPNS0_3ASTERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEE:
  234|  4.46M|        Element(AST *expr, const Fodder &comma_fodder) : expr(expr), commaFodder(comma_fodder) {}
_ZN7jsonnet8internal5ArrayC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS6_INS1_7ElementENS8_ISD_EEEEbSC_:
  246|  1.71M|    {
  247|  1.71M|    }
_ZN7jsonnet8internal18ArrayComprehensionC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_bRKNS6_INS0_17ComprehensionSpecENS8_ISF_EEEESC_:
  266|   354k|    {
  267|   354k|        assert(specs.size() > 0);
  268|   354k|    }
_ZN7jsonnet8internal6AssertC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_SE_SC_SE_:
  290|   380k|    {
  291|   380k|    }
_ZN7jsonnet8internal6BinaryC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_NS0_8BinaryOpESE_:
  366|  9.69M|    {
  367|  9.69M|    }
_ZN7jsonnet8internal15BuiltinFunctionC2ERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEERKNS5_6vectorIPKNS0_10IdentifierENS9_ISH_EEEE:
  380|   361k|    {
  381|   361k|    }
_ZN7jsonnet8internal11ConditionalC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_SE_SC_SE_:
  404|  4.63M|    {
  405|  4.63M|    }
_ZN7jsonnet8internal6DollarC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEE:
  410|  41.9k|    Dollar(const LocationRange &lr, const Fodder &open_fodder) : AST(lr, AST_DOLLAR, open_fodder) {}
_ZN7jsonnet8internal5ErrorC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTE:
  418|  1.38M|    {
  419|  1.38M|    }
_ZN7jsonnet8internal8FunctionC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEESC_RKNS6_INS0_8ArgParamENS8_ISD_EEEEbSC_PNS0_3ASTE:
  438|  2.41M|    {
  439|  2.41M|    }
_ZN7jsonnet8internal6ImportC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_13LiteralStringE:
  449|    439|    {
  450|    439|    }
_ZN7jsonnet8internal9ImportstrC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_13LiteralStringE:
  458|  3.25k|    {
  459|  3.25k|    }
_ZN7jsonnet8internal9ImportbinC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_13LiteralStringE:
  467|    209|    {
  468|    209|    }
_ZN7jsonnet8internal5IndexC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_SC_PKNS0_10IdentifierE:
  498|  6.57M|    {
  499|  6.57M|    }
_ZN7jsonnet8internal5IndexC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_bSE_SC_SE_SC_SE_SC_:
  515|  5.43M|    {
  516|  5.43M|    }
_ZN7jsonnet8internal5Local4BindC2ERKNSt3__16vectorINS0_13FodderElementENS3_9allocatorIS5_EEEEPKNS0_10IdentifierESA_PNS0_3ASTEbSA_RKNS4_INS0_8ArgParamENS6_ISG_EEEEbSA_SA_:
  545|  3.95M|        {
  546|  3.95M|        }
_ZN7jsonnet8internal5LocalC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS6_INS1_4BindENS8_ISD_EEEEPNS0_3ASTE:
  553|  4.22M|    {
  554|  4.22M|    }
_ZN7jsonnet8internal14LiteralBooleanC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEb:
  562|   811k|    {
  563|   811k|    }
_ZN7jsonnet8internal11LiteralNullC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEE:
  570|   473k|    {
  571|   473k|    }
_ZN7jsonnet8internal13LiteralNumberC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS5_12basic_stringIcNS5_11char_traitsIcEENS8_IcEEEE:
  582|  7.80M|    {
  583|  7.80M|    }
_ZN7jsonnet8internal13LiteralStringC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS5_12basic_stringIDiNS5_11char_traitsIDiEENS8_IDiEEEENS1_9TokenKindERKNSD_IcNSE_IcEENS8_IcEEEESP_:
  601|  17.6M|    {
  602|  17.6M|    }
_ZN7jsonnet8internal11ObjectFieldC2ENS1_4KindERKNSt3__16vectorINS0_13FodderElementENS3_9allocatorIS5_EEEESA_SA_SA_NS1_4HideEbbPNS0_3ASTEPKNS0_10IdentifierERKNS0_13LocationRangeERKNS4_INS0_8ArgParamENS6_ISK_EEEEbSA_SD_SD_SA_:
  683|  2.29M|    {
  684|       |        // Enforce what is written in comments above.
  685|  2.29M|        assert(kind != ASSERT || (hide == VISIBLE && !superSugar && !methodSugar));
  686|      0|        assert(kind != LOCAL || (hide == VISIBLE && !superSugar));
  687|      0|        assert(kind != FIELD_ID || (id != nullptr && expr1 == nullptr));
  688|      0|        assert(kind == FIELD_ID || kind == LOCAL || id == nullptr);
  689|      0|        assert(methodSugar || (params.size() == 0 && !trailingComma));
  690|      0|        assert(kind == ASSERT || expr3 == nullptr);
  691|  2.29M|    }
_ZN7jsonnet8internal11ObjectField5LocalERKNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEES9_S9_S9_bPKNS0_10IdentifierERKNS3_INS0_8ArgParamENS5_ISD_EEEEbS9_PNS0_3ASTES9_:
  697|  65.4k|    {
  698|  65.4k|        return ObjectField(LOCAL,
  699|  65.4k|                           fodder1,
  700|  65.4k|                           fodder2,
  701|  65.4k|                           fodder_l,
  702|  65.4k|                           fodder_r,
  703|  65.4k|                           VISIBLE,
  704|  65.4k|                           false,
  705|  65.4k|                           method_sugar,
  706|  65.4k|                           nullptr,
  707|  65.4k|                           id,
  708|  65.4k|                           LocationRange(),
  709|  65.4k|                           params,
  710|  65.4k|                           trailing_comma,
  711|  65.4k|                           op_fodder,
  712|  65.4k|                           body,
  713|  65.4k|                           nullptr,
  714|  65.4k|                           comma_fodder);
  715|  65.4k|    }
_ZN7jsonnet8internal11ObjectField5LocalERKNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEES9_PKNS0_10IdentifierES9_PNS0_3ASTES9_:
  718|  30.9k|    {
  719|  30.9k|        return ObjectField(LOCAL,
  720|  30.9k|                           fodder1,
  721|  30.9k|                           fodder2,
  722|  30.9k|                           Fodder{},
  723|  30.9k|                           Fodder{},
  724|  30.9k|                           VISIBLE,
  725|  30.9k|                           false,
  726|  30.9k|                           false,
  727|  30.9k|                           nullptr,
  728|  30.9k|                           id,
  729|  30.9k|                           LocationRange(),
  730|  30.9k|                           ArgParams{},
  731|  30.9k|                           false,
  732|  30.9k|                           op_fodder,
  733|  30.9k|                           body,
  734|  30.9k|                           nullptr,
  735|  30.9k|                           comma_fodder);
  736|  30.9k|    }
_ZN7jsonnet8internal11ObjectField6AssertERKNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEEPNS0_3ASTES9_SB_S9_:
  763|  22.3k|    {
  764|  22.3k|        return ObjectField(ASSERT,
  765|  22.3k|                           fodder1,
  766|  22.3k|                           Fodder{},
  767|  22.3k|                           Fodder{},
  768|  22.3k|                           Fodder{},
  769|  22.3k|                           VISIBLE,
  770|  22.3k|                           false,
  771|  22.3k|                           false,
  772|  22.3k|                           nullptr,
  773|  22.3k|                           nullptr,
  774|  22.3k|                           LocationRange(),
  775|  22.3k|                           ArgParams{},
  776|  22.3k|                           false,
  777|  22.3k|                           op_fodder,
  778|  22.3k|                           body,
  779|  22.3k|                           msg,
  780|  22.3k|                           comma_fodder);
  781|  22.3k|    }
_ZN7jsonnet8internal6ObjectC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS6_INS0_11ObjectFieldENS8_ISD_EEEEbSC_:
  800|   480k|    {
  801|   480k|        assert(fields.size() > 0 || !trailing_comma);
  802|   480k|        if (fields.size() > 0)
  ------------------
  |  Branch (802:13): [True: 428k, False: 51.4k]
  ------------------
  803|   428k|            assert(trailing_comma || fields[fields.size() - 1].commaFodder.size() == 0);
  804|   480k|    }
_ZN7jsonnet8internal15DesugaredObject5FieldC2ENS0_11ObjectField4HideEPNS0_3ASTES6_:
  818|  2.42M|        {
  819|  2.42M|        }
_ZN7jsonnet8internal15DesugaredObjectC2ERKNS0_13LocationRangeERKNSt3__14listIPNS0_3ASTENS5_9allocatorIS8_EEEERKNS5_6vectorINS1_5FieldENS9_ISF_EEEE:
  826|   474k|    {
  827|   474k|    }
_ZN7jsonnet8internal19ObjectComprehensionC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS6_INS0_11ObjectFieldENS8_ISD_EEEEbRKNS6_INS0_17ComprehensionSpecENS8_ISI_EEEESC_:
  845|  47.5k|    {
  846|  47.5k|    }
_ZN7jsonnet8internal25ObjectComprehensionSimpleC2ERKNS0_13LocationRangeEPNS0_3ASTES6_PKNS0_10IdentifierES6_:
  862|  47.4k|    {
  863|  47.4k|    }
_ZN7jsonnet8internal6ParensC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_:
  873|   445k|    {
  874|   445k|    }
_ZN7jsonnet8internal4SelfC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEE:
  879|  71.1k|    Self(const LocationRange &lr, const Fodder &open_fodder) : AST(lr, AST_SELF, open_fodder) {}
_ZN7jsonnet8internal10SuperIndexC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEESC_PNS0_3ASTESC_PKNS0_10IdentifierE:
  899|  24.8k|    {
  900|  24.8k|    }
_ZN7jsonnet8internal7InSuperC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_SC_:
  915|  17.0k|    {
  916|  17.0k|    }
_ZN7jsonnet8internal5UnaryC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEENS0_7UnaryOpEPNS0_3ASTE:
  941|  1.22M|    {
  942|  1.22M|    }
_ZN7jsonnet8internal3VarC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPKNS0_10IdentifierE:
  950|  38.1M|    {
  951|  38.1M|    }
_ZN7jsonnet8internal9Allocator14makeIdentifierERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEE:
  981|  62.0M|    {
  982|  62.0M|        auto it = internedIdentifiers.find(name);
  983|  62.0M|        if (it != internedIdentifiers.end()) {
  ------------------
  |  Branch (983:13): [True: 58.8M, False: 3.16M]
  ------------------
  984|  58.8M|            return it->second;
  985|  58.8M|        }
  986|  3.16M|        auto r = new Identifier(name);
  987|  3.16M|        internedIdentifiers[name] = r;
  988|  3.16M|        return r;
  989|  62.0M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1014|      2|{
 1015|      2|    std::map<BinaryOp, int> r;
 1016|       |
 1017|      2|    r[BOP_MULT] = 5;
 1018|      2|    r[BOP_DIV] = 5;
 1019|      2|    r[BOP_PERCENT] = 5;
 1020|       |
 1021|      2|    r[BOP_PLUS] = 6;
 1022|      2|    r[BOP_MINUS] = 6;
 1023|       |
 1024|      2|    r[BOP_SHIFT_L] = 7;
 1025|      2|    r[BOP_SHIFT_R] = 7;
 1026|       |
 1027|      2|    r[BOP_GREATER] = 8;
 1028|      2|    r[BOP_GREATER_EQ] = 8;
 1029|      2|    r[BOP_LESS] = 8;
 1030|      2|    r[BOP_LESS_EQ] = 8;
 1031|      2|    r[BOP_IN] = 8;
 1032|       |
 1033|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1034|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1035|       |
 1036|      2|    r[BOP_BITWISE_AND] = 10;
 1037|       |
 1038|      2|    r[BOP_BITWISE_XOR] = 11;
 1039|       |
 1040|      2|    r[BOP_BITWISE_OR] = 12;
 1041|       |
 1042|      2|    r[BOP_AND] = 13;
 1043|       |
 1044|      2|    r[BOP_OR] = 14;
 1045|       |
 1046|      2|    return r;
 1047|      2|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1050|      2|{
 1051|      2|    std::map<std::string, UnaryOp> r;
 1052|      2|    r["!"] = UOP_NOT;
 1053|      2|    r["~"] = UOP_BITWISE_NOT;
 1054|      2|    r["+"] = UOP_PLUS;
 1055|      2|    r["-"] = UOP_MINUS;
 1056|      2|    return r;
 1057|      2|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1060|      2|{
 1061|      2|    std::map<std::string, BinaryOp> r;
 1062|       |
 1063|      2|    r["*"] = BOP_MULT;
 1064|      2|    r["/"] = BOP_DIV;
 1065|      2|    r["%"] = BOP_PERCENT;
 1066|       |
 1067|      2|    r["+"] = BOP_PLUS;
 1068|      2|    r["-"] = BOP_MINUS;
 1069|       |
 1070|      2|    r["<<"] = BOP_SHIFT_L;
 1071|      2|    r[">>"] = BOP_SHIFT_R;
 1072|       |
 1073|      2|    r[">"] = BOP_GREATER;
 1074|      2|    r[">="] = BOP_GREATER_EQ;
 1075|      2|    r["<"] = BOP_LESS;
 1076|      2|    r["<="] = BOP_LESS_EQ;
 1077|      2|    r["in"] = BOP_IN;
 1078|       |
 1079|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1080|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1081|       |
 1082|      2|    r["&"] = BOP_BITWISE_AND;
 1083|      2|    r["^"] = BOP_BITWISE_XOR;
 1084|      2|    r["|"] = BOP_BITWISE_OR;
 1085|       |
 1086|      2|    r["&&"] = BOP_AND;
 1087|      2|    r["||"] = BOP_OR;
 1088|      2|    return r;
 1089|      2|}
_ZN7jsonnet8internal9Allocator4makeINS0_6AssertEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_SF_SG_SF_EEEPT_DpOT0_:
  963|   380k|    {
  964|   380k|        auto r = new T(std::forward<Args>(args)...);
  965|   380k|        allocated.push_back(r);
  966|   380k|        return r;
  967|   380k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ErrorEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  963|   588k|    {
  964|   588k|        auto r = new T(std::forward<Args>(args)...);
  965|   588k|        allocated.push_back(r);
  966|   588k|        return r;
  967|   588k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_SF_SG_SF_EEEPT_DpOT0_:
  963|  2.95M|    {
  964|  2.95M|        auto r = new T(std::forward<Args>(args)...);
  965|  2.95M|        allocated.push_back(r);
  966|  2.95M|        return r;
  967|  2.95M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_SF_SA_DnEEEPT_DpOT0_:
  963|  37.2k|    {
  964|  37.2k|        auto r = new T(std::forward<Args>(args)...);
  965|  37.2k|        allocated.push_back(r);
  966|  37.2k|        return r;
  967|  37.2k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_8FunctionEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERSA_RNS6_INS0_8ArgParamENS8_ISE_EEEERbSD_RPNS0_3ASTEEEEPT_DpOT0_:
  963|   195k|    {
  964|   195k|        auto r = new T(std::forward<Args>(args)...);
  965|   195k|        allocated.push_back(r);
  966|   195k|        return r;
  967|   195k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6ImportEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_13LiteralStringEEEEPT_DpOT0_:
  963|    439|    {
  964|    439|        auto r = new T(std::forward<Args>(args)...);
  965|    439|        allocated.push_back(r);
  966|    439|        return r;
  967|    439|    }
_ZN7jsonnet8internal9Allocator4makeINS0_9ImportstrEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_13LiteralStringEEEEPT_DpOT0_:
  963|  3.25k|    {
  964|  3.25k|        auto r = new T(std::forward<Args>(args)...);
  965|  3.25k|        allocated.push_back(r);
  966|  3.25k|        return r;
  967|  3.25k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_9ImportbinEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_13LiteralStringEEEEPT_DpOT0_:
  963|    209|    {
  964|    209|        auto r = new T(std::forward<Args>(args)...);
  965|    209|        allocated.push_back(r);
  966|    209|        return r;
  967|    209|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5LocalEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS6_INS3_4BindENS8_ISD_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  963|  2.22M|    {
  964|  2.22M|        auto r = new T(std::forward<Args>(args)...);
  965|  2.22M|        allocated.push_back(r);
  966|  2.22M|        return r;
  967|  2.22M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5UnaryEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS0_7UnaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  963|   986k|    {
  964|   986k|        auto r = new T(std::forward<Args>(args)...);
  965|   986k|        allocated.push_back(r);
  966|   986k|        return r;
  967|   986k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6ObjectEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS6_INS0_11ObjectFieldENS8_ISD_EEEERbRSA_EEEPT_DpOT0_:
  963|   480k|    {
  964|   480k|        auto r = new T(std::forward<Args>(args)...);
  965|   480k|        allocated.push_back(r);
  966|   480k|        return r;
  967|   480k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_19ObjectComprehensionEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS6_INS0_11ObjectFieldENS8_ISD_EEEERbRNS6_INS0_17ComprehensionSpecENS8_ISI_EEEERSA_EEEPT_DpOT0_:
  963|  47.5k|    {
  964|  47.5k|        auto r = new T(std::forward<Args>(args)...);
  965|  47.5k|        allocated.push_back(r);
  966|  47.5k|        return r;
  967|  47.5k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralStringEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS6_12basic_stringIDiNS6_11char_traitsIDiEENS9_IDiEEEENS3_9TokenKindERA1_KcSL_EEEPT_DpOT0_:
  963|  65.5k|    {
  964|  65.5k|        auto r = new T(std::forward<Args>(args)...);
  965|  65.5k|        allocated.push_back(r);
  966|  65.5k|        return r;
  967|  65.5k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralStringEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS6_12basic_stringIDiNS6_11char_traitsIDiEENS9_IDiEEEENS3_9TokenKindERNSD_IcNSE_IcEENS9_IcEEEESM_EEEPT_DpOT0_:
  963|    716|    {
  964|    716|        auto r = new T(std::forward<Args>(args)...);
  965|    716|        allocated.push_back(r);
  966|    716|        return r;
  967|    716|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ArrayEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEENS6_INS3_7ElementENS8_ISC_EEEEbSB_EEEPT_DpOT0_:
  963|   207k|    {
  964|   207k|        auto r = new T(std::forward<Args>(args)...);
  965|   207k|        allocated.push_back(r);
  966|   207k|        return r;
  967|   207k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_18ArrayComprehensionEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTESB_RbRNS6_INS0_17ComprehensionSpecENS8_ISG_EEEESB_EEEPT_DpOT0_:
  963|   307k|    {
  964|   307k|        auto r = new T(std::forward<Args>(args)...);
  965|   307k|        allocated.push_back(r);
  966|   307k|        return r;
  967|   307k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ArrayEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS6_INS3_7ElementENS8_ISC_EEEERbSB_EEEPT_DpOT0_:
  963|   751k|    {
  964|   751k|        auto r = new T(std::forward<Args>(args)...);
  965|   751k|        allocated.push_back(r);
  966|   751k|        return r;
  967|   751k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6ParensEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTESB_EEEPT_DpOT0_:
  963|   445k|    {
  964|   445k|        auto r = new T(std::forward<Args>(args)...);
  965|   445k|        allocated.push_back(r);
  966|   445k|        return r;
  967|   445k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralNumberEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS5_12basic_stringIcNS5_11char_traitsIcEENS8_IcEEEEEEEPT_DpOT0_:
  963|  6.99M|    {
  964|  6.99M|        auto r = new T(std::forward<Args>(args)...);
  965|  6.99M|        allocated.push_back(r);
  966|  6.99M|        return r;
  967|  6.99M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralStringEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEENS5_12basic_stringIDiNS5_11char_traitsIDiEENS8_IDiEEEENS3_9TokenKindERA1_KcSK_EEEPT_DpOT0_:
  963|  4.40M|    {
  964|  4.40M|        auto r = new T(std::forward<Args>(args)...);
  965|  4.40M|        allocated.push_back(r);
  966|  4.40M|        return r;
  967|  4.40M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralStringEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEENS5_12basic_stringIDiNS5_11char_traitsIDiEENS8_IDiEEEENS3_9TokenKindERNSC_IcNSD_IcEENS8_IcEEEESL_EEEPT_DpOT0_:
  963|  3.28k|    {
  964|  3.28k|        auto r = new T(std::forward<Args>(args)...);
  965|  3.28k|        allocated.push_back(r);
  966|  3.28k|        return r;
  967|  3.28k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_14LiteralBooleanEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEbEEEPT_DpOT0_:
  963|   790k|    {
  964|   790k|        auto r = new T(std::forward<Args>(args)...);
  965|   790k|        allocated.push_back(r);
  966|   790k|        return r;
  967|   790k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11LiteralNullEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEEEEPT_DpOT0_:
  963|   160k|    {
  964|   160k|        auto r = new T(std::forward<Args>(args)...);
  965|   160k|        allocated.push_back(r);
  966|   160k|        return r;
  967|   160k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6DollarEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEEEEPT_DpOT0_:
  963|  41.9k|    {
  964|  41.9k|        auto r = new T(std::forward<Args>(args)...);
  965|  41.9k|        allocated.push_back(r);
  966|  41.9k|        return r;
  967|  41.9k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_3VarEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPKNS0_10IdentifierEEEEPT_DpOT0_:
  963|  29.0M|    {
  964|  29.0M|        auto r = new T(std::forward<Args>(args)...);
  965|  29.0M|        allocated.push_back(r);
  966|  29.0M|        return r;
  967|  29.0M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_4SelfEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEEEEPT_DpOT0_:
  963|  38.8k|    {
  964|  38.8k|        auto r = new T(std::forward<Args>(args)...);
  965|  38.8k|        allocated.push_back(r);
  966|  38.8k|        return r;
  967|  38.8k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_10SuperIndexEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEESB_RPNS0_3ASTESB_RPKNS0_10IdentifierEEEEPT_DpOT0_:
  963|  8.22k|    {
  964|  8.22k|        auto r = new T(std::forward<Args>(args)...);
  965|  8.22k|        allocated.push_back(r);
  966|  8.22k|        return r;
  967|  8.22k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_RbSF_SG_SF_SG_SF_SG_EEEPT_DpOT0_:
  963|  1.59M|    {
  964|  1.59M|        auto r = new T(std::forward<Args>(args)...);
  965|  1.59M|        allocated.push_back(r);
  966|  1.59M|        return r;
  967|  1.59M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_SG_RPKNS0_10IdentifierEEEEPT_DpOT0_:
  963|  6.57M|    {
  964|  6.57M|        auto r = new T(std::forward<Args>(args)...);
  965|  6.57M|        allocated.push_back(r);
  966|  6.57M|        return r;
  967|  6.57M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_RNS6_INS0_8ArgParamENS8_ISH_EEEERbSG_SG_SL_EEEPT_DpOT0_:
  963|  7.48M|    {
  964|  7.48M|        auto r = new T(std::forward<Args>(args)...);
  965|  7.48M|        allocated.push_back(r);
  966|  7.48M|        return r;
  967|  7.48M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_10ApplyBraceEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTESF_EEEPT_DpOT0_:
  963|  83.1k|    {
  964|  83.1k|        auto r = new T(std::forward<Args>(args)...);
  965|  83.1k|        allocated.push_back(r);
  966|  83.1k|        return r;
  967|  83.1k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_7InSuperEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_SG_EEEPT_DpOT0_:
  963|    420|    {
  964|    420|        auto r = new T(std::forward<Args>(args)...);
  965|    420|        allocated.push_back(r);
  966|    420|        return r;
  967|    420|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_RNS0_8BinaryOpESF_EEEPT_DpOT0_:
  963|  8.02M|    {
  964|  8.02M|        auto r = new T(std::forward<Args>(args)...);
  965|  8.02M|        allocated.push_back(r);
  966|  8.02M|        return r;
  967|  8.02M|    }
static_analysis.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1014|      2|{
 1015|      2|    std::map<BinaryOp, int> r;
 1016|       |
 1017|      2|    r[BOP_MULT] = 5;
 1018|      2|    r[BOP_DIV] = 5;
 1019|      2|    r[BOP_PERCENT] = 5;
 1020|       |
 1021|      2|    r[BOP_PLUS] = 6;
 1022|      2|    r[BOP_MINUS] = 6;
 1023|       |
 1024|      2|    r[BOP_SHIFT_L] = 7;
 1025|      2|    r[BOP_SHIFT_R] = 7;
 1026|       |
 1027|      2|    r[BOP_GREATER] = 8;
 1028|      2|    r[BOP_GREATER_EQ] = 8;
 1029|      2|    r[BOP_LESS] = 8;
 1030|      2|    r[BOP_LESS_EQ] = 8;
 1031|      2|    r[BOP_IN] = 8;
 1032|       |
 1033|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1034|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1035|       |
 1036|      2|    r[BOP_BITWISE_AND] = 10;
 1037|       |
 1038|      2|    r[BOP_BITWISE_XOR] = 11;
 1039|       |
 1040|      2|    r[BOP_BITWISE_OR] = 12;
 1041|       |
 1042|      2|    r[BOP_AND] = 13;
 1043|       |
 1044|      2|    r[BOP_OR] = 14;
 1045|       |
 1046|      2|    return r;
 1047|      2|}
static_analysis.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1050|      2|{
 1051|      2|    std::map<std::string, UnaryOp> r;
 1052|      2|    r["!"] = UOP_NOT;
 1053|      2|    r["~"] = UOP_BITWISE_NOT;
 1054|      2|    r["+"] = UOP_PLUS;
 1055|      2|    r["-"] = UOP_MINUS;
 1056|      2|    return r;
 1057|      2|}
static_analysis.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1060|      2|{
 1061|      2|    std::map<std::string, BinaryOp> r;
 1062|       |
 1063|      2|    r["*"] = BOP_MULT;
 1064|      2|    r["/"] = BOP_DIV;
 1065|      2|    r["%"] = BOP_PERCENT;
 1066|       |
 1067|      2|    r["+"] = BOP_PLUS;
 1068|      2|    r["-"] = BOP_MINUS;
 1069|       |
 1070|      2|    r["<<"] = BOP_SHIFT_L;
 1071|      2|    r[">>"] = BOP_SHIFT_R;
 1072|       |
 1073|      2|    r[">"] = BOP_GREATER;
 1074|      2|    r[">="] = BOP_GREATER_EQ;
 1075|      2|    r["<"] = BOP_LESS;
 1076|      2|    r["<="] = BOP_LESS_EQ;
 1077|      2|    r["in"] = BOP_IN;
 1078|       |
 1079|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1080|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1081|       |
 1082|      2|    r["&"] = BOP_BITWISE_AND;
 1083|      2|    r["^"] = BOP_BITWISE_XOR;
 1084|      2|    r["|"] = BOP_BITWISE_OR;
 1085|       |
 1086|      2|    r["&&"] = BOP_AND;
 1087|      2|    r["||"] = BOP_OR;
 1088|      2|    return r;
 1089|      2|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1014|      2|{
 1015|      2|    std::map<BinaryOp, int> r;
 1016|       |
 1017|      2|    r[BOP_MULT] = 5;
 1018|      2|    r[BOP_DIV] = 5;
 1019|      2|    r[BOP_PERCENT] = 5;
 1020|       |
 1021|      2|    r[BOP_PLUS] = 6;
 1022|      2|    r[BOP_MINUS] = 6;
 1023|       |
 1024|      2|    r[BOP_SHIFT_L] = 7;
 1025|      2|    r[BOP_SHIFT_R] = 7;
 1026|       |
 1027|      2|    r[BOP_GREATER] = 8;
 1028|      2|    r[BOP_GREATER_EQ] = 8;
 1029|      2|    r[BOP_LESS] = 8;
 1030|      2|    r[BOP_LESS_EQ] = 8;
 1031|      2|    r[BOP_IN] = 8;
 1032|       |
 1033|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1034|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1035|       |
 1036|      2|    r[BOP_BITWISE_AND] = 10;
 1037|       |
 1038|      2|    r[BOP_BITWISE_XOR] = 11;
 1039|       |
 1040|      2|    r[BOP_BITWISE_OR] = 12;
 1041|       |
 1042|      2|    r[BOP_AND] = 13;
 1043|       |
 1044|      2|    r[BOP_OR] = 14;
 1045|       |
 1046|      2|    return r;
 1047|      2|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1050|      2|{
 1051|      2|    std::map<std::string, UnaryOp> r;
 1052|      2|    r["!"] = UOP_NOT;
 1053|      2|    r["~"] = UOP_BITWISE_NOT;
 1054|      2|    r["+"] = UOP_PLUS;
 1055|      2|    r["-"] = UOP_MINUS;
 1056|      2|    return r;
 1057|      2|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1060|      2|{
 1061|      2|    std::map<std::string, BinaryOp> r;
 1062|       |
 1063|      2|    r["*"] = BOP_MULT;
 1064|      2|    r["/"] = BOP_DIV;
 1065|      2|    r["%"] = BOP_PERCENT;
 1066|       |
 1067|      2|    r["+"] = BOP_PLUS;
 1068|      2|    r["-"] = BOP_MINUS;
 1069|       |
 1070|      2|    r["<<"] = BOP_SHIFT_L;
 1071|      2|    r[">>"] = BOP_SHIFT_R;
 1072|       |
 1073|      2|    r[">"] = BOP_GREATER;
 1074|      2|    r[">="] = BOP_GREATER_EQ;
 1075|      2|    r["<"] = BOP_LESS;
 1076|      2|    r["<="] = BOP_LESS_EQ;
 1077|      2|    r["in"] = BOP_IN;
 1078|       |
 1079|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1080|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1081|       |
 1082|      2|    r["&"] = BOP_BITWISE_AND;
 1083|      2|    r["^"] = BOP_BITWISE_XOR;
 1084|      2|    r["|"] = BOP_BITWISE_OR;
 1085|       |
 1086|      2|    r["&&"] = BOP_AND;
 1087|      2|    r["||"] = BOP_OR;
 1088|      2|    return r;
 1089|      2|}
_ZN7jsonnet8internal9Allocator4makeINS0_3VarEJNS0_13LocationRangeENSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  963|  4.16k|    {
  964|  4.16k|        auto r = new T(std::forward<Args>(args)...);
  965|  4.16k|        allocated.push_back(r);
  966|  4.16k|        return r;
  967|  4.16k|    }
vm.cpp:_ZN7jsonnet8internalL10bop_stringENS0_8BinaryOpE:
  323|    163|{
  324|    163|    switch (bop) {
  325|      6|        case BOP_MULT: return "*";
  ------------------
  |  Branch (325:9): [True: 6, False: 157]
  ------------------
  326|      4|        case BOP_DIV: return "/";
  ------------------
  |  Branch (326:9): [True: 4, False: 159]
  ------------------
  327|      0|        case BOP_PERCENT: return "%";
  ------------------
  |  Branch (327:9): [True: 0, False: 163]
  ------------------
  328|       |
  329|     44|        case BOP_PLUS: return "+";
  ------------------
  |  Branch (329:9): [True: 44, False: 119]
  ------------------
  330|     23|        case BOP_MINUS: return "-";
  ------------------
  |  Branch (330:9): [True: 23, False: 140]
  ------------------
  331|       |
  332|      2|        case BOP_SHIFT_L: return "<<";
  ------------------
  |  Branch (332:9): [True: 2, False: 161]
  ------------------
  333|      1|        case BOP_SHIFT_R: return ">>";
  ------------------
  |  Branch (333:9): [True: 1, False: 162]
  ------------------
  334|       |
  335|     14|        case BOP_GREATER: return ">";
  ------------------
  |  Branch (335:9): [True: 14, False: 149]
  ------------------
  336|     21|        case BOP_GREATER_EQ: return ">=";
  ------------------
  |  Branch (336:9): [True: 21, False: 142]
  ------------------
  337|     12|        case BOP_LESS: return "<";
  ------------------
  |  Branch (337:9): [True: 12, False: 151]
  ------------------
  338|      8|        case BOP_LESS_EQ: return "<=";
  ------------------
  |  Branch (338:9): [True: 8, False: 155]
  ------------------
  339|      0|        case BOP_IN: return "in";
  ------------------
  |  Branch (339:9): [True: 0, False: 163]
  ------------------
  340|       |
  341|      0|        case BOP_MANIFEST_EQUAL: return "==";
  ------------------
  |  Branch (341:9): [True: 0, False: 163]
  ------------------
  342|      0|        case BOP_MANIFEST_UNEQUAL: return "!=";
  ------------------
  |  Branch (342:9): [True: 0, False: 163]
  ------------------
  343|       |
  344|      5|        case BOP_BITWISE_AND: return "&";
  ------------------
  |  Branch (344:9): [True: 5, False: 158]
  ------------------
  345|     12|        case BOP_BITWISE_XOR: return "^";
  ------------------
  |  Branch (345:9): [True: 12, False: 151]
  ------------------
  346|      2|        case BOP_BITWISE_OR: return "|";
  ------------------
  |  Branch (346:9): [True: 2, False: 161]
  ------------------
  347|       |
  348|      4|        case BOP_AND: return "&&";
  ------------------
  |  Branch (348:9): [True: 4, False: 159]
  ------------------
  349|      5|        case BOP_OR: return "||";
  ------------------
  |  Branch (349:9): [True: 5, False: 158]
  ------------------
  350|       |
  351|      0|        default:
  ------------------
  |  Branch (351:9): [True: 0, False: 163]
  ------------------
  352|      0|            std::cerr << "INTERNAL ERROR: Unrecognised binary operator: " << bop << std::endl;
  353|      0|            std::abort();
  354|    163|    }
  355|    163|}
vm.cpp:_ZN7jsonnet8internalL10uop_stringENS0_7UnaryOpE:
  922|     86|{
  923|     86|    switch (uop) {
  924|     48|        case UOP_PLUS: return "+";
  ------------------
  |  Branch (924:9): [True: 48, False: 38]
  ------------------
  925|     10|        case UOP_MINUS: return "-";
  ------------------
  |  Branch (925:9): [True: 10, False: 76]
  ------------------
  926|      3|        case UOP_BITWISE_NOT: return "~";
  ------------------
  |  Branch (926:9): [True: 3, False: 83]
  ------------------
  927|     25|        case UOP_NOT: return "!";
  ------------------
  |  Branch (927:9): [True: 25, False: 61]
  ------------------
  928|       |
  929|      0|        default:
  ------------------
  |  Branch (929:9): [True: 0, False: 86]
  ------------------
  930|      0|            std::cerr << "INTERNAL ERROR: Unrecognised unary operator: " << uop << std::endl;
  931|      0|            std::abort();
  932|     86|    }
  933|     86|}
desugarer.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1014|      2|{
 1015|      2|    std::map<BinaryOp, int> r;
 1016|       |
 1017|      2|    r[BOP_MULT] = 5;
 1018|      2|    r[BOP_DIV] = 5;
 1019|      2|    r[BOP_PERCENT] = 5;
 1020|       |
 1021|      2|    r[BOP_PLUS] = 6;
 1022|      2|    r[BOP_MINUS] = 6;
 1023|       |
 1024|      2|    r[BOP_SHIFT_L] = 7;
 1025|      2|    r[BOP_SHIFT_R] = 7;
 1026|       |
 1027|      2|    r[BOP_GREATER] = 8;
 1028|      2|    r[BOP_GREATER_EQ] = 8;
 1029|      2|    r[BOP_LESS] = 8;
 1030|      2|    r[BOP_LESS_EQ] = 8;
 1031|      2|    r[BOP_IN] = 8;
 1032|       |
 1033|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1034|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1035|       |
 1036|      2|    r[BOP_BITWISE_AND] = 10;
 1037|       |
 1038|      2|    r[BOP_BITWISE_XOR] = 11;
 1039|       |
 1040|      2|    r[BOP_BITWISE_OR] = 12;
 1041|       |
 1042|      2|    r[BOP_AND] = 13;
 1043|       |
 1044|      2|    r[BOP_OR] = 14;
 1045|       |
 1046|      2|    return r;
 1047|      2|}
desugarer.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1050|      2|{
 1051|      2|    std::map<std::string, UnaryOp> r;
 1052|      2|    r["!"] = UOP_NOT;
 1053|      2|    r["~"] = UOP_BITWISE_NOT;
 1054|      2|    r["+"] = UOP_PLUS;
 1055|      2|    r["-"] = UOP_MINUS;
 1056|      2|    return r;
 1057|      2|}
desugarer.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1060|      2|{
 1061|      2|    std::map<std::string, BinaryOp> r;
 1062|       |
 1063|      2|    r["*"] = BOP_MULT;
 1064|      2|    r["/"] = BOP_DIV;
 1065|      2|    r["%"] = BOP_PERCENT;
 1066|       |
 1067|      2|    r["+"] = BOP_PLUS;
 1068|      2|    r["-"] = BOP_MINUS;
 1069|       |
 1070|      2|    r["<<"] = BOP_SHIFT_L;
 1071|      2|    r[">>"] = BOP_SHIFT_R;
 1072|       |
 1073|      2|    r[">"] = BOP_GREATER;
 1074|      2|    r[">="] = BOP_GREATER_EQ;
 1075|      2|    r["<"] = BOP_LESS;
 1076|      2|    r["<="] = BOP_LESS_EQ;
 1077|      2|    r["in"] = BOP_IN;
 1078|       |
 1079|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1080|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1081|       |
 1082|      2|    r["&"] = BOP_BITWISE_AND;
 1083|      2|    r["^"] = BOP_BITWISE_XOR;
 1084|      2|    r["|"] = BOP_BITWISE_OR;
 1085|       |
 1086|      2|    r["&&"] = BOP_AND;
 1087|      2|    r["||"] = BOP_OR;
 1088|      2|    return r;
 1089|      2|}
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_NS0_8BinaryOpESF_EEEPT_DpOT0_:
  963|  80.2k|    {
  964|  80.2k|        auto r = new T(std::forward<Args>(args)...);
  965|  80.2k|        allocated.push_back(r);
  966|  80.2k|        return r;
  967|  80.2k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralNumberEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERA4_KcEEEPT_DpOT0_:
  963|   755k|    {
  964|   755k|        auto r = new T(std::forward<Args>(args)...);
  965|   755k|        allocated.push_back(r);
  966|   755k|        return r;
  967|   755k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_3VarESD_NS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  963|   354k|    {
  964|   354k|        auto r = new T(std::forward<Args>(args)...);
  965|   354k|        allocated.push_back(r);
  966|   354k|        return r;
  967|   354k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  963|   827k|    {
  964|   827k|        auto r = new T(std::forward<Args>(args)...);
  965|   827k|        allocated.push_back(r);
  966|   827k|        return r;
  967|   827k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpEPNS0_5ArrayEEEEPT_DpOT0_:
  963|   354k|    {
  964|   354k|        auto r = new T(std::forward<Args>(args)...);
  965|   354k|        allocated.push_back(r);
  966|   354k|        return r;
  967|   354k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ArrayEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_7ElementENS9_ISE_EEEEbSD_EEEPT_DpOT0_:
  963|   354k|    {
  964|   354k|        auto r = new T(std::forward<Args>(args)...);
  965|   354k|        allocated.push_back(r);
  966|   354k|        return r;
  967|   354k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS8_INS0_8ArgParamENSA_ISH_EEEEbSE_SE_bEEEPT_DpOT0_:
  963|   865k|    {
  964|   865k|        auto r = new T(std::forward<Args>(args)...);
  965|   865k|        allocated.push_back(r);
  966|   865k|        return r;
  967|   865k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERKPNS0_3ASTESD_RSF_SD_SI_EEEPT_DpOT0_:
  963|   435k|    {
  964|   435k|        auto r = new T(std::forward<Args>(args)...);
  965|   435k|        allocated.push_back(r);
  966|   435k|        return r;
  967|   435k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISE_EEEEPNS0_11ConditionalEEEEPT_DpOT0_:
  963|   392k|    {
  964|   392k|        auto r = new T(std::forward<Args>(args)...);
  965|   392k|        allocated.push_back(r);
  966|   392k|        return r;
  967|   392k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_8FunctionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESD_NS7_INS0_8ArgParamENS9_ISE_EEEEbSD_PNS0_11ConditionalEEEEPT_DpOT0_:
  963|   392k|    {
  964|   392k|        auto r = new T(std::forward<Args>(args)...);
  965|   392k|        allocated.push_back(r);
  966|   392k|        return r;
  967|   392k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_6BinaryESD_RPNS0_3ASTESD_PNS0_5LocalEEEEPT_DpOT0_:
  963|   392k|    {
  964|   392k|        auto r = new T(std::forward<Args>(args)...);
  965|   392k|        allocated.push_back(r);
  966|   392k|        return r;
  967|   392k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpEPNS0_5ApplyEEEEPT_DpOT0_:
  963|   392k|    {
  964|   392k|        auto r = new T(std::forward<Args>(args)...);
  965|   392k|        allocated.push_back(r);
  966|   392k|        return r;
  967|   392k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISE_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  963|   397k|    {
  964|   397k|        auto r = new T(std::forward<Args>(args)...);
  965|   397k|        allocated.push_back(r);
  966|   397k|        return r;
  967|   397k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bSG_SE_DnSE_DnSE_EEEPT_DpOT0_:
  963|   392k|    {
  964|   392k|        auto r = new T(std::forward<Args>(args)...);
  965|   392k|        allocated.push_back(r);
  966|   392k|        return r;
  967|   392k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5ApplyESD_SF_SD_PNS0_5ErrorEEEEPT_DpOT0_:
  963|   392k|    {
  964|   392k|        auto r = new T(std::forward<Args>(args)...);
  965|   392k|        allocated.push_back(r);
  966|   392k|        return r;
  967|   392k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ArrayEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEENS8_INS3_7ElementENSA_ISF_EEEEbSE_EEEPT_DpOT0_:
  963|   354k|    {
  964|   354k|        auto r = new T(std::forward<Args>(args)...);
  965|   354k|        allocated.push_back(r);
  966|   354k|        return r;
  967|   354k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralStringEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERKNS7_12basic_stringIDiNS7_11char_traitsIDiEENSA_IDiEEEENS3_9TokenKindERA1_KcSP_EEEPT_DpOT0_:
  963|  13.1M|    {
  964|  13.1M|        auto r = new T(std::forward<Args>(args)...);
  965|  13.1M|        allocated.push_back(r);
  966|  13.1M|        return r;
  967|  13.1M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ErrorEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  963|   794k|    {
  964|   794k|        auto r = new T(std::forward<Args>(args)...);
  965|   794k|        allocated.push_back(r);
  966|   794k|        return r;
  967|   794k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_SF_SH_SF_EEEPT_DpOT0_:
  963|   380k|    {
  964|   380k|        auto r = new T(std::forward<Args>(args)...);
  965|   380k|        allocated.push_back(r);
  966|   380k|        return r;
  967|   380k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bPNS0_13LiteralStringESE_DnSE_DnSE_EEEPT_DpOT0_:
  963|  3.34M|    {
  964|  3.34M|        auto r = new T(std::forward<Args>(args)...);
  965|  3.34M|        allocated.push_back(r);
  966|  3.34M|        return r;
  967|  3.34M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_RNS7_INS0_8ArgParamENS9_ISI_EEEEbSH_SH_bEEEPT_DpOT0_:
  963|   305k|    {
  964|   305k|        auto r = new T(std::forward<Args>(args)...);
  965|   305k|        allocated.push_back(r);
  966|   305k|        return r;
  967|   305k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_5IndexESE_NS8_INS0_8ArgParamENSA_ISH_EEEEbSE_SE_bEEEPT_DpOT0_:
  963|  2.08M|    {
  964|  2.08M|        auto r = new T(std::forward<Args>(args)...);
  965|  2.08M|        allocated.push_back(r);
  966|  2.08M|        return r;
  967|  2.08M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5UnaryEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS0_7UnaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  963|   234k|    {
  964|   234k|        auto r = new T(std::forward<Args>(args)...);
  965|   234k|        allocated.push_back(r);
  966|   234k|        return r;
  967|   234k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11LiteralNullEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEEEEPT_DpOT0_:
  963|   313k|    {
  964|   313k|        auto r = new T(std::forward<Args>(args)...);
  965|   313k|        allocated.push_back(r);
  966|   313k|        return r;
  967|   313k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_3VarEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  963|  8.77M|    {
  964|  8.77M|        auto r = new T(std::forward<Args>(args)...);
  965|  8.77M|        allocated.push_back(r);
  966|  8.77M|        return r;
  967|  8.77M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5IndexESD_NS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  963|   959k|    {
  964|   959k|        auto r = new T(std::forward<Args>(args)...);
  965|   959k|        allocated.push_back(r);
  966|   959k|        return r;
  967|   959k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_8FunctionEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESC_RNS7_INS0_8ArgParamENS9_ISD_EEEEbSC_RPNS0_3ASTEEEEPT_DpOT0_:
  963|   705k|    {
  964|   705k|        auto r = new T(std::forward<Args>(args)...);
  965|   705k|        allocated.push_back(r);
  966|   705k|        return r;
  967|   705k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_4SelfEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEEEEPT_DpOT0_:
  963|  32.2k|    {
  964|  32.2k|        auto r = new T(std::forward<Args>(args)...);
  965|  32.2k|        allocated.push_back(r);
  966|  32.2k|        return r;
  967|  32.2k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTESD_PNS0_14LiteralBooleanESD_PNS0_5ErrorEEEEPT_DpOT0_:
  963|  21.6k|    {
  964|  21.6k|        auto r = new T(std::forward<Args>(args)...);
  965|  21.6k|        allocated.push_back(r);
  966|  21.6k|        return r;
  967|  21.6k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_14LiteralBooleanEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEbEEEPT_DpOT0_:
  963|  21.6k|    {
  964|  21.6k|        auto r = new T(std::forward<Args>(args)...);
  965|  21.6k|        allocated.push_back(r);
  966|  21.6k|        return r;
  967|  21.6k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_8FunctionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERSB_RNS7_INS0_8ArgParamENS9_ISF_EEEERbSE_RPNS0_3ASTEEEEPT_DpOT0_:
  963|  1.12M|    {
  964|  1.12M|        auto r = new T(std::forward<Args>(args)...);
  965|  1.12M|        allocated.push_back(r);
  966|  1.12M|        return r;
  967|  1.12M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_3VarEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  963|   279k|    {
  964|   279k|        auto r = new T(std::forward<Args>(args)...);
  965|   279k|        allocated.push_back(r);
  966|   279k|        return r;
  967|   279k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_7InSuperESD_PNS0_6BinaryESD_PNS0_3ASTEEEEPT_DpOT0_:
  963|  16.5k|    {
  964|  16.5k|        auto r = new T(std::forward<Args>(args)...);
  965|  16.5k|        allocated.push_back(r);
  966|  16.5k|        return r;
  967|  16.5k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_7InSuperEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTESD_SD_EEEPT_DpOT0_:
  963|  16.5k|    {
  964|  16.5k|        auto r = new T(std::forward<Args>(args)...);
  965|  16.5k|        allocated.push_back(r);
  966|  16.5k|        return r;
  967|  16.5k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_10SuperIndexESD_NS0_8BinaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  963|  16.5k|    {
  964|  16.5k|        auto r = new T(std::forward<Args>(args)...);
  965|  16.5k|        allocated.push_back(r);
  966|  16.5k|        return r;
  967|  16.5k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_10SuperIndexEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESD_PNS0_3ASTESD_DnEEEPT_DpOT0_:
  963|  16.5k|    {
  964|  16.5k|        auto r = new T(std::forward<Args>(args)...);
  965|  16.5k|        allocated.push_back(r);
  966|  16.5k|        return r;
  967|  16.5k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_15DesugaredObjectEJRNS0_13LocationRangeERNSt3__14listIPNS0_3ASTENS6_9allocatorIS9_EEEERNS6_6vectorINS3_5FieldENSA_ISF_EEEEEEEPT_DpOT0_:
  963|   474k|    {
  964|   474k|        auto r = new T(std::forward<Args>(args)...);
  965|   474k|        allocated.push_back(r);
  966|   474k|        return r;
  967|   474k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERNS7_INS3_4BindENS9_ISE_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  963|  1.20M|    {
  964|  1.20M|        auto r = new T(std::forward<Args>(args)...);
  965|  1.20M|        allocated.push_back(r);
  966|  1.20M|        return r;
  967|  1.20M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bPNS0_13LiteralNumberESE_DnSE_DnSE_EEEPT_DpOT0_:
  963|  54.6k|    {
  964|  54.6k|        auto r = new T(std::forward<Args>(args)...);
  965|  54.6k|        allocated.push_back(r);
  966|  54.6k|        return r;
  967|  54.6k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralNumberEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEENS7_12basic_stringIcNS7_11char_traitsIcEENSA_IcEEEEEEEPT_DpOT0_:
  963|  54.6k|    {
  964|  54.6k|        auto r = new T(std::forward<Args>(args)...);
  965|  54.6k|        allocated.push_back(r);
  966|  54.6k|        return r;
  967|  54.6k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_18ArrayComprehensionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5ArrayESD_bRNS7_INS0_17ComprehensionSpecENS9_ISG_EEEESD_EEEPT_DpOT0_:
  963|  47.4k|    {
  964|  47.4k|        auto r = new T(std::forward<Args>(args)...);
  965|  47.4k|        allocated.push_back(r);
  966|  47.4k|        return r;
  967|  47.4k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ArrayEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERNS7_INS3_7ElementENS9_ISE_EEEEbSD_EEEPT_DpOT0_:
  963|  47.4k|    {
  964|  47.4k|        auto r = new T(std::forward<Args>(args)...);
  965|  47.4k|        allocated.push_back(r);
  966|  47.4k|        return r;
  967|  47.4k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_25ObjectComprehensionSimpleEJRNS0_13LocationRangeEPNS0_5IndexEPNS0_5LocalERPKNS0_10IdentifierERPNS0_3ASTEEEEPT_DpOT0_:
  963|  47.4k|    {
  964|  47.4k|        auto r = new T(std::forward<Args>(args)...);
  965|  47.4k|        allocated.push_back(r);
  966|  47.4k|        return r;
  967|  47.4k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bRPNS0_3ASTESE_DnSE_DnSE_EEEPT_DpOT0_:
  963|  47.4k|    {
  964|  47.4k|        auto r = new T(std::forward<Args>(args)...);
  965|  47.4k|        allocated.push_back(r);
  966|  47.4k|        return r;
  967|  47.4k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_15BuiltinFunctionEJRKNS0_13LocationRangeENSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEERNS7_6vectorIPKNS0_10IdentifierENSB_ISH_EEEEEEEPT_DpOT0_:
  963|   361k|    {
  964|   361k|        auto r = new T(std::forward<Args>(args)...);
  965|   361k|        allocated.push_back(r);
  966|   361k|        return r;
  967|   361k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5LocalEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISD_EEEEPNS0_11ConditionalEEEEPT_DpOT0_:
  963|  5.11k|    {
  964|  5.11k|        auto r = new T(std::forward<Args>(args)...);
  965|  5.11k|        allocated.push_back(r);
  966|  5.11k|        return r;
  967|  5.11k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRKNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_5ApplyERKSC_SF_SD_PNS0_3VarEEEEPT_DpOT0_:
  963|  5.11k|    {
  964|  5.11k|        auto r = new T(std::forward<Args>(args)...);
  965|  5.11k|        allocated.push_back(r);
  966|  5.11k|        return r;
  967|  5.11k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_3VarESD_RNS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  963|  5.11k|    {
  964|  5.11k|        auto r = new T(std::forward<Args>(args)...);
  965|  5.11k|        allocated.push_back(r);
  966|  5.11k|        return r;
  967|  5.11k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_3VarEJRKNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  963|  10.2k|    {
  964|  10.2k|        auto r = new T(std::forward<Args>(args)...);
  965|  10.2k|        allocated.push_back(r);
  966|  10.2k|        return r;
  967|  10.2k|    }
formatter.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1014|      2|{
 1015|      2|    std::map<BinaryOp, int> r;
 1016|       |
 1017|      2|    r[BOP_MULT] = 5;
 1018|      2|    r[BOP_DIV] = 5;
 1019|      2|    r[BOP_PERCENT] = 5;
 1020|       |
 1021|      2|    r[BOP_PLUS] = 6;
 1022|      2|    r[BOP_MINUS] = 6;
 1023|       |
 1024|      2|    r[BOP_SHIFT_L] = 7;
 1025|      2|    r[BOP_SHIFT_R] = 7;
 1026|       |
 1027|      2|    r[BOP_GREATER] = 8;
 1028|      2|    r[BOP_GREATER_EQ] = 8;
 1029|      2|    r[BOP_LESS] = 8;
 1030|      2|    r[BOP_LESS_EQ] = 8;
 1031|      2|    r[BOP_IN] = 8;
 1032|       |
 1033|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1034|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1035|       |
 1036|      2|    r[BOP_BITWISE_AND] = 10;
 1037|       |
 1038|      2|    r[BOP_BITWISE_XOR] = 11;
 1039|       |
 1040|      2|    r[BOP_BITWISE_OR] = 12;
 1041|       |
 1042|      2|    r[BOP_AND] = 13;
 1043|       |
 1044|      2|    r[BOP_OR] = 14;
 1045|       |
 1046|      2|    return r;
 1047|      2|}
formatter.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1050|      2|{
 1051|      2|    std::map<std::string, UnaryOp> r;
 1052|      2|    r["!"] = UOP_NOT;
 1053|      2|    r["~"] = UOP_BITWISE_NOT;
 1054|      2|    r["+"] = UOP_PLUS;
 1055|      2|    r["-"] = UOP_MINUS;
 1056|      2|    return r;
 1057|      2|}
formatter.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1060|      2|{
 1061|      2|    std::map<std::string, BinaryOp> r;
 1062|       |
 1063|      2|    r["*"] = BOP_MULT;
 1064|      2|    r["/"] = BOP_DIV;
 1065|      2|    r["%"] = BOP_PERCENT;
 1066|       |
 1067|      2|    r["+"] = BOP_PLUS;
 1068|      2|    r["-"] = BOP_MINUS;
 1069|       |
 1070|      2|    r["<<"] = BOP_SHIFT_L;
 1071|      2|    r[">>"] = BOP_SHIFT_R;
 1072|       |
 1073|      2|    r[">"] = BOP_GREATER;
 1074|      2|    r[">="] = BOP_GREATER_EQ;
 1075|      2|    r["<"] = BOP_LESS;
 1076|      2|    r["<="] = BOP_LESS_EQ;
 1077|      2|    r["in"] = BOP_IN;
 1078|       |
 1079|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1080|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1081|       |
 1082|      2|    r["&"] = BOP_BITWISE_AND;
 1083|      2|    r["^"] = BOP_BITWISE_XOR;
 1084|      2|    r["|"] = BOP_BITWISE_OR;
 1085|       |
 1086|      2|    r["&&"] = BOP_AND;
 1087|      2|    r["||"] = BOP_OR;
 1088|      2|    return r;
 1089|      2|}
pass.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1014|      2|{
 1015|      2|    std::map<BinaryOp, int> r;
 1016|       |
 1017|      2|    r[BOP_MULT] = 5;
 1018|      2|    r[BOP_DIV] = 5;
 1019|      2|    r[BOP_PERCENT] = 5;
 1020|       |
 1021|      2|    r[BOP_PLUS] = 6;
 1022|      2|    r[BOP_MINUS] = 6;
 1023|       |
 1024|      2|    r[BOP_SHIFT_L] = 7;
 1025|      2|    r[BOP_SHIFT_R] = 7;
 1026|       |
 1027|      2|    r[BOP_GREATER] = 8;
 1028|      2|    r[BOP_GREATER_EQ] = 8;
 1029|      2|    r[BOP_LESS] = 8;
 1030|      2|    r[BOP_LESS_EQ] = 8;
 1031|      2|    r[BOP_IN] = 8;
 1032|       |
 1033|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1034|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1035|       |
 1036|      2|    r[BOP_BITWISE_AND] = 10;
 1037|       |
 1038|      2|    r[BOP_BITWISE_XOR] = 11;
 1039|       |
 1040|      2|    r[BOP_BITWISE_OR] = 12;
 1041|       |
 1042|      2|    r[BOP_AND] = 13;
 1043|       |
 1044|      2|    r[BOP_OR] = 14;
 1045|       |
 1046|      2|    return r;
 1047|      2|}
pass.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1050|      2|{
 1051|      2|    std::map<std::string, UnaryOp> r;
 1052|      2|    r["!"] = UOP_NOT;
 1053|      2|    r["~"] = UOP_BITWISE_NOT;
 1054|      2|    r["+"] = UOP_PLUS;
 1055|      2|    r["-"] = UOP_MINUS;
 1056|      2|    return r;
 1057|      2|}
pass.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1060|      2|{
 1061|      2|    std::map<std::string, BinaryOp> r;
 1062|       |
 1063|      2|    r["*"] = BOP_MULT;
 1064|      2|    r["/"] = BOP_DIV;
 1065|      2|    r["%"] = BOP_PERCENT;
 1066|       |
 1067|      2|    r["+"] = BOP_PLUS;
 1068|      2|    r["-"] = BOP_MINUS;
 1069|       |
 1070|      2|    r["<<"] = BOP_SHIFT_L;
 1071|      2|    r[">>"] = BOP_SHIFT_R;
 1072|       |
 1073|      2|    r[">"] = BOP_GREATER;
 1074|      2|    r[">="] = BOP_GREATER_EQ;
 1075|      2|    r["<"] = BOP_LESS;
 1076|      2|    r["<="] = BOP_LESS_EQ;
 1077|      2|    r["in"] = BOP_IN;
 1078|       |
 1079|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1080|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1081|       |
 1082|      2|    r["&"] = BOP_BITWISE_AND;
 1083|      2|    r["^"] = BOP_BITWISE_XOR;
 1084|      2|    r["|"] = BOP_BITWISE_OR;
 1085|       |
 1086|      2|    r["&&"] = BOP_AND;
 1087|      2|    r["||"] = BOP_OR;
 1088|      2|    return r;
 1089|      2|}
_ZN7jsonnet8internal9Allocator5cloneINS0_5ApplyEEEPT_S5_:
  971|   631k|    {
  972|   631k|        auto r = new T(*ast);
  973|   631k|        allocated.push_back(r);
  974|   631k|        return r;
  975|   631k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_5ArrayEEEPT_S5_:
  971|   172k|    {
  972|   172k|        auto r = new T(*ast);
  973|   172k|        allocated.push_back(r);
  974|   172k|        return r;
  975|   172k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_6BinaryEEEPT_S5_:
  971|  1.26M|    {
  972|  1.26M|        auto r = new T(*ast);
  973|  1.26M|        allocated.push_back(r);
  974|  1.26M|        return r;
  975|  1.26M|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_11ConditionalEEEPT_S5_:
  971|   422k|    {
  972|   422k|        auto r = new T(*ast);
  973|   422k|        allocated.push_back(r);
  974|   422k|        return r;
  975|   422k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_15DesugaredObjectEEEPT_S5_:
  971|   720k|    {
  972|   720k|        auto r = new T(*ast);
  973|   720k|        allocated.push_back(r);
  974|   720k|        return r;
  975|   720k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_5ErrorEEEPT_S5_:
  971|  52.2k|    {
  972|  52.2k|        auto r = new T(*ast);
  973|  52.2k|        allocated.push_back(r);
  974|  52.2k|        return r;
  975|  52.2k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_8FunctionEEEPT_S5_:
  971|  32.6k|    {
  972|  32.6k|        auto r = new T(*ast);
  973|  32.6k|        allocated.push_back(r);
  974|  32.6k|        return r;
  975|  32.6k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_6ImportEEEPT_S5_:
  971|    254|    {
  972|    254|        auto r = new T(*ast);
  973|    254|        allocated.push_back(r);
  974|    254|        return r;
  975|    254|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_9ImportstrEEEPT_S5_:
  971|  12.3k|    {
  972|  12.3k|        auto r = new T(*ast);
  973|  12.3k|        allocated.push_back(r);
  974|  12.3k|        return r;
  975|  12.3k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_9ImportbinEEEPT_S5_:
  971|     68|    {
  972|     68|        auto r = new T(*ast);
  973|     68|        allocated.push_back(r);
  974|     68|        return r;
  975|     68|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_5IndexEEEPT_S5_:
  971|   716k|    {
  972|   716k|        auto r = new T(*ast);
  973|   716k|        allocated.push_back(r);
  974|   716k|        return r;
  975|   716k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_7InSuperEEEPT_S5_:
  971|   170k|    {
  972|   170k|        auto r = new T(*ast);
  973|   170k|        allocated.push_back(r);
  974|   170k|        return r;
  975|   170k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_14LiteralBooleanEEEPT_S5_:
  971|  34.3k|    {
  972|  34.3k|        auto r = new T(*ast);
  973|  34.3k|        allocated.push_back(r);
  974|  34.3k|        return r;
  975|  34.3k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_11LiteralNullEEEPT_S5_:
  971|  52.7k|    {
  972|  52.7k|        auto r = new T(*ast);
  973|  52.7k|        allocated.push_back(r);
  974|  52.7k|        return r;
  975|  52.7k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_13LiteralNumberEEEPT_S5_:
  971|   983k|    {
  972|   983k|        auto r = new T(*ast);
  973|   983k|        allocated.push_back(r);
  974|   983k|        return r;
  975|   983k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_13LiteralStringEEEPT_S5_:
  971|  1.60M|    {
  972|  1.60M|        auto r = new T(*ast);
  973|  1.60M|        allocated.push_back(r);
  974|  1.60M|        return r;
  975|  1.60M|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_5LocalEEEPT_S5_:
  971|   313k|    {
  972|   313k|        auto r = new T(*ast);
  973|   313k|        allocated.push_back(r);
  974|   313k|        return r;
  975|   313k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_25ObjectComprehensionSimpleEEEPT_S5_:
  971|  27.4k|    {
  972|  27.4k|        auto r = new T(*ast);
  973|  27.4k|        allocated.push_back(r);
  974|  27.4k|        return r;
  975|  27.4k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_4SelfEEEPT_S5_:
  971|  13.5k|    {
  972|  13.5k|        auto r = new T(*ast);
  973|  13.5k|        allocated.push_back(r);
  974|  13.5k|        return r;
  975|  13.5k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_10SuperIndexEEEPT_S5_:
  971|   200k|    {
  972|   200k|        auto r = new T(*ast);
  973|   200k|        allocated.push_back(r);
  974|   200k|        return r;
  975|   200k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_5UnaryEEEPT_S5_:
  971|  8.36M|    {
  972|  8.36M|        auto r = new T(*ast);
  973|  8.36M|        allocated.push_back(r);
  974|  8.36M|        return r;
  975|  8.36M|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_3VarEEEPT_S5_:
  971|  3.00M|    {
  972|  3.00M|        auto r = new T(*ast);
  973|  3.00M|        allocated.push_back(r);
  974|  3.00M|        return r;
  975|  3.00M|    }

_ZN7jsonnet8internal20jsonnet_builtin_declEm:
   41|   361k|{
   42|   361k|    switch (builtin) {
   43|  9.28k|        case 0: return {U"makeArray", {U"sz", U"func"}};
  ------------------
  |  Branch (43:9): [True: 9.28k, False: 352k]
  ------------------
   44|  9.28k|        case 1: return {U"pow", {U"x", U"n"}};
  ------------------
  |  Branch (44:9): [True: 9.28k, False: 352k]
  ------------------
   45|  9.28k|        case 2: return {U"floor", {U"x"}};
  ------------------
  |  Branch (45:9): [True: 9.28k, False: 352k]
  ------------------
   46|  9.28k|        case 3: return {U"ceil", {U"x"}};
  ------------------
  |  Branch (46:9): [True: 9.28k, False: 352k]
  ------------------
   47|  9.28k|        case 4: return {U"sqrt", {U"x"}};
  ------------------
  |  Branch (47:9): [True: 9.28k, False: 352k]
  ------------------
   48|  9.28k|        case 5: return {U"sin", {U"x"}};
  ------------------
  |  Branch (48:9): [True: 9.28k, False: 352k]
  ------------------
   49|  9.28k|        case 6: return {U"cos", {U"x"}};
  ------------------
  |  Branch (49:9): [True: 9.28k, False: 352k]
  ------------------
   50|  9.28k|        case 7: return {U"tan", {U"x"}};
  ------------------
  |  Branch (50:9): [True: 9.28k, False: 352k]
  ------------------
   51|  9.28k|        case 8: return {U"asin", {U"x"}};
  ------------------
  |  Branch (51:9): [True: 9.28k, False: 352k]
  ------------------
   52|  9.28k|        case 9: return {U"acos", {U"x"}};
  ------------------
  |  Branch (52:9): [True: 9.28k, False: 352k]
  ------------------
   53|  9.28k|        case 10: return {U"atan", {U"x"}};
  ------------------
  |  Branch (53:9): [True: 9.28k, False: 352k]
  ------------------
   54|  9.28k|        case 11: return {U"type", {U"x"}};
  ------------------
  |  Branch (54:9): [True: 9.28k, False: 352k]
  ------------------
   55|  9.28k|        case 12: return {U"filter", {U"func", U"arr"}};
  ------------------
  |  Branch (55:9): [True: 9.28k, False: 352k]
  ------------------
   56|  9.28k|        case 13: return {U"objectHasEx", {U"obj", U"f", U"inc_hidden"}};
  ------------------
  |  Branch (56:9): [True: 9.28k, False: 352k]
  ------------------
   57|  9.28k|        case 14: return {U"length", {U"x"}};
  ------------------
  |  Branch (57:9): [True: 9.28k, False: 352k]
  ------------------
   58|  9.28k|        case 15: return {U"objectFieldsEx", {U"obj", U"inc_hidden"}};
  ------------------
  |  Branch (58:9): [True: 9.28k, False: 352k]
  ------------------
   59|  9.28k|        case 16: return {U"codepoint", {U"str"}};
  ------------------
  |  Branch (59:9): [True: 9.28k, False: 352k]
  ------------------
   60|  9.28k|        case 17: return {U"char", {U"n"}};
  ------------------
  |  Branch (60:9): [True: 9.28k, False: 352k]
  ------------------
   61|  9.28k|        case 18: return {U"log", {U"n"}};
  ------------------
  |  Branch (61:9): [True: 9.28k, False: 352k]
  ------------------
   62|  9.28k|        case 19: return {U"exp", {U"n"}};
  ------------------
  |  Branch (62:9): [True: 9.28k, False: 352k]
  ------------------
   63|  9.28k|        case 20: return {U"mantissa", {U"n"}};
  ------------------
  |  Branch (63:9): [True: 9.28k, False: 352k]
  ------------------
   64|  9.28k|        case 21: return {U"exponent", {U"n"}};
  ------------------
  |  Branch (64:9): [True: 9.28k, False: 352k]
  ------------------
   65|  9.28k|        case 22: return {U"modulo", {U"a", U"b"}};
  ------------------
  |  Branch (65:9): [True: 9.28k, False: 352k]
  ------------------
   66|  9.28k|        case 23: return {U"extVar", {U"x"}};
  ------------------
  |  Branch (66:9): [True: 9.28k, False: 352k]
  ------------------
   67|  9.28k|        case 24: return {U"primitiveEquals", {U"a", U"b"}};
  ------------------
  |  Branch (67:9): [True: 9.28k, False: 352k]
  ------------------
   68|  9.28k|        case 25: return {U"native", {U"name"}};
  ------------------
  |  Branch (68:9): [True: 9.28k, False: 352k]
  ------------------
   69|  9.28k|        case 26: return {U"md5", {U"str"}};
  ------------------
  |  Branch (69:9): [True: 9.28k, False: 352k]
  ------------------
   70|  9.28k|        case 27: return {U"trace", {U"str", U"rest"}};
  ------------------
  |  Branch (70:9): [True: 9.28k, False: 352k]
  ------------------
   71|  9.28k|        case 28: return {U"splitLimit", {U"str", U"c", U"maxsplits"}};
  ------------------
  |  Branch (71:9): [True: 9.28k, False: 352k]
  ------------------
   72|  9.28k|        case 29: return {U"substr", {U"str", U"from", U"len"}};
  ------------------
  |  Branch (72:9): [True: 9.28k, False: 352k]
  ------------------
   73|  9.28k|        case 30: return {U"range", {U"from", U"to"}};
  ------------------
  |  Branch (73:9): [True: 9.28k, False: 352k]
  ------------------
   74|  9.28k|        case 31: return {U"strReplace", {U"str", U"from", U"to"}};
  ------------------
  |  Branch (74:9): [True: 9.28k, False: 352k]
  ------------------
   75|  9.28k|        case 32: return {U"asciiLower", {U"str"}};
  ------------------
  |  Branch (75:9): [True: 9.28k, False: 352k]
  ------------------
   76|  9.28k|        case 33: return {U"asciiUpper", {U"str"}};
  ------------------
  |  Branch (76:9): [True: 9.28k, False: 352k]
  ------------------
   77|  9.28k|        case 34: return {U"join", {U"sep", U"arr"}};
  ------------------
  |  Branch (77:9): [True: 9.28k, False: 352k]
  ------------------
   78|  9.28k|        case 35: return {U"parseJson", {U"str"}};
  ------------------
  |  Branch (78:9): [True: 9.28k, False: 352k]
  ------------------
   79|  9.28k|        case 36: return {U"parseYaml", {U"str"}};
  ------------------
  |  Branch (79:9): [True: 9.28k, False: 352k]
  ------------------
   80|  9.28k|        case 37: return {U"encodeUTF8", {U"str"}};
  ------------------
  |  Branch (80:9): [True: 9.28k, False: 352k]
  ------------------
   81|  9.28k|        case 38: return {U"decodeUTF8", {U"arr"}};
  ------------------
  |  Branch (81:9): [True: 9.28k, False: 352k]
  ------------------
   82|      0|        default:
  ------------------
  |  Branch (82:9): [True: 0, False: 361k]
  ------------------
   83|      0|            std::cerr << "INTERNAL ERROR: Unrecognized builtin function: " << builtin << std::endl;
   84|      0|            std::abort();
   85|   361k|    }
   86|       |    // Quiet, compiler.
   87|      0|    return BuiltinDecl();
   88|   361k|}
_ZN7jsonnet8internal13makeStdlibASTEPNS0_9AllocatorENSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
 1006|  4.16k|DesugaredObject *makeStdlibAST(Allocator *alloc, std::string filename) {
 1007|  4.16k|    Desugarer desugarer(alloc);
 1008|  4.16k|    return desugarer.stdlibAST(filename);
 1009|  4.16k|}
_ZN7jsonnet8internal15jsonnet_desugarEPNS0_9AllocatorERPNS0_3ASTEPNSt3__13mapINS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEENS0_5VmExtENS6_4lessISD_EENSB_INS6_4pairIKSD_SE_EEEEEE:
 1012|  5.70k|{
 1013|  5.70k|    Desugarer desugarer(alloc);
 1014|  5.70k|    desugarer.desugarFile(ast, tlas);
 1015|  5.70k|}
_ZN7jsonnet8internal9DesugarerC2EPNS0_9AllocatorE:
  222|  9.87k|    Desugarer(Allocator *alloc) : alloc(alloc) {}
_ZN7jsonnet8internal9Desugarer9stdlibASTENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  913|  9.28k|    DesugaredObject *stdlibAST(std::string filename) {
  914|       |        // Now, implement the std library by wrapping in a local construct.
  915|  9.28k|        Tokens tokens = jsonnet_lex("std.jsonnet", STD_CODE);
  916|  9.28k|        AST *std_ast = jsonnet_parse(alloc, tokens);
  917|  9.28k|        desugar(std_ast, 0);
  918|  9.28k|        auto *std_obj = dynamic_cast<DesugaredObject *>(std_ast);
  919|  9.28k|        if (std_obj == nullptr) {
  ------------------
  |  Branch (919:13): [True: 0, False: 9.28k]
  ------------------
  920|      0|            std::cerr << "INTERNAL ERROR: std.jsonnet not an object." << std::endl;
  921|      0|            std::abort();
  922|      0|        }
  923|       |
  924|       |        // Bind 'std' builtins that are implemented natively.
  925|  9.28k|        DesugaredObject::Fields &fields = std_obj->fields;
  926|   371k|        for (unsigned long c = 0; c <= max_builtin; ++c) {
  ------------------
  |  Branch (926:35): [True: 361k, False: 9.28k]
  ------------------
  927|   361k|            const auto &decl = jsonnet_builtin_decl(c);
  928|   361k|            Identifiers params;
  929|   361k|            for (const auto &p : decl.params)
  ------------------
  |  Branch (929:32): [True: 519k, False: 361k]
  ------------------
  930|   519k|                params.push_back(id(p));
  931|   361k|            auto name = str(decl.name);
  932|   361k|            auto fn = make<BuiltinFunction>(E, encode_utf8(decl.name), params);
  933|   361k|            auto field = std::find_if(fields.begin(), fields.end(),
  934|   361k|                [=](const DesugaredObject::Field& f) {
  935|   361k|                    return static_cast<LiteralString*>(f.name)->value == decl.name;
  936|   361k|                });
  937|   361k|            if (field != fields.end()) {
  ------------------
  |  Branch (937:17): [True: 64.9k, False: 296k]
  ------------------
  938|  64.9k|                field->body = fn;
  939|   296k|            } else {
  940|   296k|                fields.emplace_back(ObjectField::HIDDEN, name, fn);
  941|   296k|            }
  942|   361k|        }
  943|  9.28k|        fields.emplace_back(
  944|  9.28k|            ObjectField::HIDDEN, str(U"thisFile"), str(decode_utf8(filename)));
  945|  9.28k|        return std_obj;
  946|  9.28k|    }
_ZN7jsonnet8internal9Desugarer7desugarERPNS0_3ASTEj:
  679|  79.1M|    {
  680|  79.1M|        if (auto *ast = dynamic_cast<Apply *>(ast_)) {
  ------------------
  |  Branch (680:19): [True: 7.57M, False: 71.5M]
  ------------------
  681|  7.57M|            desugar(ast->target, obj_level);
  682|  7.57M|            for (ArgParam &arg : ast->args)
  ------------------
  |  Branch (682:32): [True: 12.5M, False: 7.57M]
  ------------------
  683|  12.5M|                desugar(arg.expr, obj_level);
  684|       |
  685|  71.5M|        } else if (auto *ast = dynamic_cast<ApplyBrace *>(ast_)) {
  ------------------
  |  Branch (685:26): [True: 80.3k, False: 71.4M]
  ------------------
  686|  80.3k|            desugar(ast->left, obj_level);
  687|  80.3k|            desugar(ast->right, obj_level);
  688|  80.3k|            ast_ =
  689|  80.3k|                make<Binary>(ast->location, ast->openFodder, ast->left, EF, BOP_PLUS, ast->right);
  690|       |
  691|  71.4M|        } else if (auto *ast = dynamic_cast<Array *>(ast_)) {
  ------------------
  |  Branch (691:26): [True: 1.05M, False: 70.3M]
  ------------------
  692|  1.05M|            for (auto &el : ast->elements)
  ------------------
  |  Branch (692:27): [True: 4.09M, False: 1.05M]
  ------------------
  693|  4.09M|                desugar(el.expr, obj_level);
  694|       |
  695|  70.3M|        } else if (auto *ast = dynamic_cast<ArrayComprehension *>(ast_)) {
  ------------------
  |  Branch (695:26): [True: 354k, False: 70.0M]
  ------------------
  696|   354k|            for (ComprehensionSpec &spec : ast->specs)
  ------------------
  |  Branch (696:42): [True: 827k, False: 354k]
  ------------------
  697|   827k|                desugar(spec.expr, obj_level);
  698|   354k|            desugar(ast->body, obj_level + 1);
  699|       |
  700|   354k|            ast_ = makeArrayComprehension(ast);
  701|       |
  702|  70.0M|        } else if (auto *ast = dynamic_cast<Assert *>(ast_)) {
  ------------------
  |  Branch (702:26): [True: 380k, False: 69.6M]
  ------------------
  703|   380k|            desugar(ast->cond, obj_level);
  704|   380k|            if (ast->message == nullptr) {
  ------------------
  |  Branch (704:17): [True: 28.2k, False: 352k]
  ------------------
  705|  28.2k|                ast->message = str(U"Assertion failed.");
  706|  28.2k|            }
  707|   380k|            desugar(ast->message, obj_level);
  708|   380k|            desugar(ast->rest, obj_level);
  709|       |
  710|       |            // if cond then rest else error msg
  711|   380k|            AST *branch_false = make<Error>(ast->location, EF, ast->message);
  712|   380k|            ast_ = make<Conditional>(
  713|   380k|                ast->location, ast->openFodder, ast->cond, EF, ast->rest, EF, branch_false);
  714|       |
  715|  69.6M|        } else if (auto *ast = dynamic_cast<Binary *>(ast_)) {
  ------------------
  |  Branch (715:26): [True: 8.13M, False: 61.5M]
  ------------------
  716|  8.13M|            desugar(ast->left, obj_level);
  717|  8.13M|            desugar(ast->right, obj_level);
  718|       |
  719|  8.13M|            bool invert = false;
  720|       |
  721|  8.13M|            switch (ast->op) {
  722|   305k|                case BOP_PERCENT: {
  ------------------
  |  Branch (722:17): [True: 305k, False: 7.82M]
  ------------------
  723|   305k|                    AST *f_mod = make<Index>(
  724|   305k|                        E, EF, std(), EF, false, str(U"mod"), EF, nullptr, EF, nullptr, EF);
  725|   305k|                    ArgParams args = {{ast->left, EF}, {ast->right, EF}};
  726|   305k|                    ast_ = make<Apply>(
  727|   305k|                        ast->location, ast->openFodder, f_mod, EF, args, false, EF, EF, false);
  728|   305k|                } break;
  729|       |
  730|   234k|                case BOP_MANIFEST_UNEQUAL: invert = true;
  ------------------
  |  Branch (730:17): [True: 234k, False: 7.89M]
  ------------------
  731|       |                /* fallthrough */
  732|  1.68M|                case BOP_MANIFEST_EQUAL: {
  ------------------
  |  Branch (732:17): [True: 1.45M, False: 6.68M]
  ------------------
  733|  1.68M|                    ast_ = equals(ast->location, ast->left, ast->right);
  734|  1.68M|                    if (invert)
  ------------------
  |  Branch (734:25): [True: 234k, False: 1.45M]
  ------------------
  735|   234k|                        ast_ = make<Unary>(ast->location, ast->openFodder, UOP_NOT, ast_);
  736|  1.68M|                } break;
  737|       |
  738|  6.14M|                default:;
  ------------------
  |  Branch (738:17): [True: 6.14M, False: 1.99M]
  ------------------
  739|       |                    // Otherwise don't change it.
  740|  8.13M|            }
  741|       |
  742|  61.5M|        } else if (dynamic_cast<const BuiltinFunction *>(ast_)) {
  ------------------
  |  Branch (742:20): [True: 0, False: 61.5M]
  ------------------
  743|       |            // Nothing to do.
  744|       |
  745|  61.5M|        } else if (auto *ast = dynamic_cast<Conditional *>(ast_)) {
  ------------------
  |  Branch (745:26): [True: 3.04M, False: 58.4M]
  ------------------
  746|  3.04M|            desugar(ast->cond, obj_level);
  747|  3.04M|            desugar(ast->branchTrue, obj_level);
  748|  3.04M|            if (ast->branchFalse == nullptr)
  ------------------
  |  Branch (748:17): [True: 37.1k, False: 3.00M]
  ------------------
  749|  37.1k|                ast->branchFalse = null();
  750|  3.04M|            desugar(ast->branchFalse, obj_level);
  751|       |
  752|  58.4M|        } else if (auto *ast = dynamic_cast<Dollar *>(ast_)) {
  ------------------
  |  Branch (752:26): [True: 38.7k, False: 58.4M]
  ------------------
  753|  38.7k|            if (obj_level == 0) {
  ------------------
  |  Branch (753:17): [True: 262, False: 38.4k]
  ------------------
  754|    262|                throw StaticError(ast->location, "No top-level object found.");
  755|    262|            }
  756|  38.4k|            ast_ = var(id(U"$"));
  757|       |
  758|  58.4M|        } else if (auto *ast = dynamic_cast<Error *>(ast_)) {
  ------------------
  |  Branch (758:26): [True: 605k, False: 57.8M]
  ------------------
  759|   605k|            desugar(ast->expr, obj_level);
  760|       |
  761|  57.8M|        } else if (auto *ast = dynamic_cast<Function *>(ast_)) {
  ------------------
  |  Branch (761:26): [True: 211k, False: 57.6M]
  ------------------
  762|   211k|            desugar(ast->body, obj_level);
  763|   211k|            desugarParams(ast->params, obj_level);
  764|       |
  765|  57.6M|        } else if (auto *ast = dynamic_cast<Import *>(ast_)) {
  ------------------
  |  Branch (765:26): [True: 259, False: 57.6M]
  ------------------
  766|       |            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
  767|    259|            AST *file = ast->file;
  768|    259|            desugar(file, obj_level);
  769|    259|            ast->file = dynamic_cast<LiteralString *>(file);
  770|       |
  771|  57.6M|        } else if (auto *ast = dynamic_cast<Importstr *>(ast_)) {
  ------------------
  |  Branch (771:26): [True: 3.12k, False: 57.6M]
  ------------------
  772|       |            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
  773|  3.12k|            AST *file = ast->file;
  774|  3.12k|            desugar(file, obj_level);
  775|  3.12k|            ast->file = dynamic_cast<LiteralString *>(file);
  776|       |
  777|  57.6M|        } else if (auto *ast = dynamic_cast<Importbin *>(ast_)) {
  ------------------
  |  Branch (777:26): [True: 75, False: 57.6M]
  ------------------
  778|       |            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
  779|     75|            AST *file = ast->file;
  780|     75|            desugar(file, obj_level);
  781|     75|            ast->file = dynamic_cast<LiteralString *>(file);
  782|       |
  783|  57.6M|        } else if (auto *ast = dynamic_cast<InSuper *>(ast_)) {
  ------------------
  |  Branch (783:26): [True: 6.47k, False: 57.6M]
  ------------------
  784|  6.47k|            desugar(ast->element, obj_level);
  785|       |
  786|  57.6M|        } else if (auto *ast = dynamic_cast<Index *>(ast_)) {
  ------------------
  |  Branch (786:26): [True: 8.28M, False: 49.3M]
  ------------------
  787|  8.28M|            desugar(ast->target, obj_level);
  788|  8.28M|            if (ast->isSlice) {
  ------------------
  |  Branch (788:17): [True: 170k, False: 8.11M]
  ------------------
  789|   170k|                if (ast->index == nullptr)
  ------------------
  |  Branch (789:21): [True: 21.0k, False: 148k]
  ------------------
  790|  21.0k|                    ast->index = null();
  791|   170k|                desugar(ast->index, obj_level);
  792|       |
  793|   170k|                if (ast->end == nullptr)
  ------------------
  |  Branch (793:21): [True: 94.9k, False: 75.0k]
  ------------------
  794|  94.9k|                    ast->end = null();
  795|   170k|                desugar(ast->end, obj_level);
  796|       |
  797|   170k|                if (ast->step == nullptr)
  ------------------
  |  Branch (797:21): [True: 160k, False: 9.59k]
  ------------------
  798|   160k|                    ast->step = null();
  799|   170k|                desugar(ast->step, obj_level);
  800|       |
  801|   170k|                ast_ = make<Apply>(
  802|   170k|                    ast->location,
  803|   170k|                    EF,
  804|   170k|                    make<Index>(
  805|   170k|                        E, EF, std(), EF, false, str(U"slice"), EF, nullptr, EF, nullptr, EF),
  806|   170k|                    EF,
  807|   170k|                    ArgParams{
  808|   170k|                        {ast->target, EF},
  809|   170k|                        {ast->index, EF},
  810|   170k|                        {ast->end, EF},
  811|   170k|                        {ast->step, EF},
  812|   170k|                    },
  813|   170k|                    false,  // trailing comma
  814|   170k|                    EF,
  815|   170k|                    EF,
  816|   170k|                    false  // tailstrict
  817|   170k|                );
  818|  8.11M|            } else {
  819|  8.11M|                if (ast->id != nullptr) {
  ------------------
  |  Branch (819:21): [True: 6.57M, False: 1.53M]
  ------------------
  820|  6.57M|                    assert(ast->index == nullptr);
  821|      0|                    ast->index = str(ast->id->name);
  822|  6.57M|                    ast->id = nullptr;
  823|  6.57M|                }
  824|      0|                desugar(ast->index, obj_level);
  825|  8.11M|            }
  826|       |
  827|  49.3M|        } else if (auto *ast = dynamic_cast<Local *>(ast_)) {
  ------------------
  |  Branch (827:26): [True: 2.27M, False: 47.0M]
  ------------------
  828|  2.27M|            for (auto &bind : ast->binds)
  ------------------
  |  Branch (828:29): [True: 2.43M, False: 2.27M]
  ------------------
  829|  2.43M|                desugar(bind.body, obj_level);
  830|  2.27M|            desugar(ast->body, obj_level);
  831|       |
  832|  2.43M|            for (auto &bind : ast->binds) {
  ------------------
  |  Branch (832:29): [True: 2.43M, False: 2.27M]
  ------------------
  833|  2.43M|                if (bind.functionSugar) {
  ------------------
  |  Branch (833:21): [True: 705k, False: 1.73M]
  ------------------
  834|   705k|                    desugarParams(bind.params, obj_level);
  835|   705k|                    bind.body = make<Function>(ast->location,
  836|   705k|                                               ast->openFodder,
  837|   705k|                                               bind.parenLeftFodder,
  838|   705k|                                               bind.params,
  839|   705k|                                               false,
  840|   705k|                                               bind.parenRightFodder,
  841|   705k|                                               bind.body);
  842|   705k|                    bind.functionSugar = false;
  843|   705k|                    bind.params.clear();
  844|   705k|                }
  845|  2.43M|            }
  846|       |
  847|  47.0M|        } else if (dynamic_cast<const LiteralBoolean *>(ast_)) {
  ------------------
  |  Branch (847:20): [True: 791k, False: 46.2M]
  ------------------
  848|       |            // Nothing to do.
  849|       |
  850|  46.2M|        } else if (dynamic_cast<const LiteralNumber *>(ast_)) {
  ------------------
  |  Branch (850:20): [True: 6.47M, False: 39.7M]
  ------------------
  851|       |            // Nothing to do.
  852|       |
  853|  39.7M|        } else if (auto *ast = dynamic_cast<LiteralString *>(ast_)) {
  ------------------
  |  Branch (853:26): [True: 11.2M, False: 28.5M]
  ------------------
  854|  11.2M|            if ((ast->tokenKind != LiteralString::BLOCK) &&
  ------------------
  |  Branch (854:17): [True: 11.2M, False: 511]
  ------------------
  855|  11.2M|                (ast->tokenKind != LiteralString::VERBATIM_DOUBLE) &&
  ------------------
  |  Branch (855:17): [True: 11.2M, False: 692]
  ------------------
  856|  11.2M|                (ast->tokenKind != LiteralString::VERBATIM_SINGLE)) {
  ------------------
  |  Branch (856:17): [True: 11.2M, False: 743]
  ------------------
  857|  11.2M|                ast->value = jsonnet_string_unescape(ast->location, ast->value);
  858|  11.2M|            }
  859|  11.2M|            ast->tokenKind = LiteralString::DOUBLE;
  860|  11.2M|            ast->blockIndent.clear();
  861|       |
  862|  28.5M|        } else if (dynamic_cast<const LiteralNull *>(ast_)) {
  ------------------
  |  Branch (862:20): [True: 473k, False: 28.1M]
  ------------------
  863|       |            // Nothing to do.
  864|       |
  865|  28.1M|        } else if (auto *ast = dynamic_cast<DesugaredObject *>(ast_)) {
  ------------------
  |  Branch (865:26): [True: 22.4k, False: 28.0M]
  ------------------
  866|  22.4k|            for (auto &field : ast->fields) {
  ------------------
  |  Branch (866:30): [True: 11.6k, False: 22.4k]
  ------------------
  867|  11.6k|                desugar(field.name, obj_level);
  868|  11.6k|                desugar(field.body, obj_level + 1);
  869|  11.6k|            }
  870|  22.4k|            for (AST *assert : ast->asserts) {
  ------------------
  |  Branch (870:30): [True: 1.55k, False: 22.4k]
  ------------------
  871|  1.55k|                desugar(assert, obj_level + 1);
  872|  1.55k|            }
  873|       |
  874|  28.0M|        } else if (auto *ast = dynamic_cast<Object *>(ast_)) {
  ------------------
  |  Branch (874:26): [True: 474k, False: 27.6M]
  ------------------
  875|   474k|            ast_ = makeObject(ast, obj_level);
  876|       |
  877|  27.6M|        } else if (auto *ast = dynamic_cast<ObjectComprehension *>(ast_)) {
  ------------------
  |  Branch (877:26): [True: 47.4k, False: 27.5M]
  ------------------
  878|  47.4k|            ast_ = makeObjectComprehension(ast, obj_level);
  879|       |
  880|  27.5M|        } else if (auto *ast = dynamic_cast<ObjectComprehensionSimple *>(ast_)) {
  ------------------
  |  Branch (880:26): [True: 15.7k, False: 27.5M]
  ------------------
  881|  15.7k|            desugar(ast->field, obj_level);
  882|  15.7k|            desugar(ast->value, obj_level + 1);
  883|  15.7k|            desugar(ast->array, obj_level);
  884|       |
  885|  27.5M|        } else if (auto *ast = dynamic_cast<Parens *>(ast_)) {
  ------------------
  |  Branch (885:26): [True: 445k, False: 27.0M]
  ------------------
  886|       |            // Strip parens.
  887|   445k|            desugar(ast->expr, obj_level);
  888|   445k|            ast_ = ast->expr;
  889|       |
  890|  27.0M|        } else if (dynamic_cast<const Self *>(ast_)) {
  ------------------
  |  Branch (890:20): [True: 69.4k, False: 27.0M]
  ------------------
  891|       |            // Nothing to do.
  892|       |
  893|  27.0M|        } else if (auto *ast = dynamic_cast<SuperIndex *>(ast_)) {
  ------------------
  |  Branch (893:26): [True: 12.9k, False: 27.0M]
  ------------------
  894|  12.9k|            if (ast->id != nullptr) {
  ------------------
  |  Branch (894:17): [True: 6.60k, False: 6.29k]
  ------------------
  895|  6.60k|                assert(ast->index == nullptr);
  896|      0|                ast->index = str(ast->id->name);
  897|  6.60k|                ast->id = nullptr;
  898|  6.60k|            }
  899|      0|            desugar(ast->index, obj_level);
  900|       |
  901|  27.0M|        } else if (auto *ast = dynamic_cast<Unary *>(ast_)) {
  ------------------
  |  Branch (901:26): [True: 1.30M, False: 25.7M]
  ------------------
  902|  1.30M|            desugar(ast->expr, obj_level);
  903|       |
  904|  25.7M|        } else if (dynamic_cast<const Var *>(ast_)) {
  ------------------
  |  Branch (904:20): [True: 25.7M, False: 0]
  ------------------
  905|       |            // Nothing to do.
  906|       |
  907|  25.7M|        } else {
  908|      0|            std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
  909|      0|            std::abort();
  910|      0|        }
  911|  79.1M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_6BinaryEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_NS0_8BinaryOpESF_EEEPT_DpOT0_:
  106|  80.2k|    {
  107|  80.2k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  80.2k|    }
_ZN7jsonnet8internal9Desugarer22makeArrayComprehensionEPNS0_18ArrayComprehensionE:
  410|   354k|    AST* makeArrayComprehension(ArrayComprehension *ast) {
  411|   354k|        int n = ast->specs.size();
  412|   354k|        AST *zero = make<LiteralNumber>(E, EF, "0.0");
  413|   354k|        AST *one = make<LiteralNumber>(E, EF, "1.0");
  414|   354k|        auto *_r = id(U"$r");
  415|   354k|        auto *_l = id(U"$l");
  416|   354k|        std::vector<const Identifier *> _i(n);
  417|  1.18M|        for (int i = 0; i < n; ++i) {
  ------------------
  |  Branch (417:25): [True: 827k, False: 354k]
  ------------------
  418|   827k|            UStringStream ss;
  419|   827k|            ss << U"$i_" << i;
  420|   827k|            _i[i] = id(ss.str());
  421|   827k|        }
  422|   354k|        std::vector<const Identifier *> _aux(n);
  423|  1.18M|        for (int i = 0; i < n; ++i) {
  ------------------
  |  Branch (423:25): [True: 827k, False: 354k]
  ------------------
  424|   827k|            UStringStream ss;
  425|   827k|            ss << U"$aux_" << i;
  426|   827k|            _aux[i] = id(ss.str());
  427|   827k|        }
  428|       |
  429|       |        // Build it from the inside out.  We keep wrapping 'in' with more ASTs.
  430|   354k|        assert(ast->specs[0].kind == ComprehensionSpec::FOR);
  431|       |
  432|      0|        int last_for = n - 1;
  433|   788k|        while (ast->specs[last_for].kind != ComprehensionSpec::FOR)
  ------------------
  |  Branch (433:16): [True: 434k, False: 354k]
  ------------------
  434|   434k|            last_for--;
  435|       |        // $aux_{last_for}($i_{last_for} + 1, $r + [body])
  436|   354k|        AST *in = make<Apply>(
  437|   354k|            ast->body->location,
  438|   354k|            EF,
  439|   354k|            var(_aux[last_for]),
  440|   354k|            EF,
  441|   354k|            ArgParams{{make<Binary>(E, EF, var(_i[last_for]), EF, BOP_PLUS, one), EF},
  442|   354k|                {make<Binary>(E, EF, var(_r), EF, BOP_PLUS, singleton(ast->body)), EF}},
  443|   354k|            false,  // trailingComma
  444|   354k|            EF,
  445|   354k|            EF,
  446|   354k|            true  // tailstrict
  447|   354k|        );
  448|  1.18M|        for (int i = n - 1; i >= 0; --i) {
  ------------------
  |  Branch (448:29): [True: 827k, False: 354k]
  ------------------
  449|   827k|            const ComprehensionSpec &spec = ast->specs[i];
  450|   827k|            AST *out;
  451|   827k|            if (i > 0) {
  ------------------
  |  Branch (451:17): [True: 473k, False: 354k]
  ------------------
  452|   473k|                int prev_for = i - 1;
  453|  3.60G|                while (ast->specs[prev_for].kind != ComprehensionSpec::FOR)
  ------------------
  |  Branch (453:24): [True: 3.60G, False: 473k]
  ------------------
  454|  3.60G|                    prev_for--;
  455|       |
  456|       |                // aux_{prev_for}($i_{prev_for} + 1, $r)
  457|   473k|                out = make<Apply>(  // False branch.
  458|   473k|                    E,
  459|   473k|                    EF,
  460|   473k|                    var(_aux[prev_for]),
  461|   473k|                    EF,
  462|   473k|                    ArgParams{{
  463|   473k|                        make<Binary>(E, EF, var(_i[prev_for]), EF, BOP_PLUS, one),
  464|   473k|                            EF,
  465|   473k|                            },
  466|   473k|                      {
  467|   473k|                        var(_r),
  468|   473k|                            EF,
  469|   473k|                            }},
  470|   473k|                    false,  // trailingComma
  471|   473k|                    EF,
  472|   473k|                    EF,
  473|   473k|                    true  // tailstrict
  474|   473k|                );
  475|   473k|            } else {
  476|   354k|                out = var(_r);
  477|   354k|            }
  478|   827k|            switch (spec.kind) {
  ------------------
  |  Branch (478:21): [True: 0, False: 827k]
  ------------------
  479|   435k|                case ComprehensionSpec::IF: {
  ------------------
  |  Branch (479:17): [True: 435k, False: 392k]
  ------------------
  480|       |                  /*
  481|       |                    if [[[...cond...]]] then
  482|       |                    [[[...in...]]]
  483|       |                    else
  484|       |                    [[[...out...]]]
  485|       |                  */
  486|   435k|                    in = make<Conditional>(ast->location,
  487|   435k|                                           EF,
  488|   435k|                                           spec.expr,
  489|   435k|                                           EF,
  490|   435k|                                           in,  // True branch.
  491|   435k|                                           EF,
  492|   435k|                                           out);  // False branch.
  493|   435k|                } break;
  494|   392k|                case ComprehensionSpec::FOR: {
  ------------------
  |  Branch (494:17): [True: 392k, False: 435k]
  ------------------
  495|       |                    /*
  496|       |                      local $l = [[[...array...]]]
  497|       |                      aux_{i}(i_{i}, r) =
  498|       |                      if i_{i} >= std.length($l) then
  499|       |                      [[[...out...]]]
  500|       |                      else
  501|       |                      local [[[...var...]]] = $l[i_{i}];
  502|       |                      [[[...in...]]];
  503|       |                      if std.type($l) == "array" then
  504|       |                      aux_{i}(0, $r) tailstrict
  505|       |                      else
  506|       |                      error "In comprehension, can only iterate over array..";
  507|       |                    */
  508|   392k|                    in = make<Local>(
  509|   392k|                        ast->location,
  510|   392k|                        EF,
  511|   392k|                        Local::Binds{
  512|   392k|                          bind(_l, spec.expr),  // Need to check expr is an array
  513|   392k|                              bind(_aux[i],
  514|   392k|                                   make<Function>(
  515|   392k|                                       ast->location,
  516|   392k|                                       EF,
  517|   392k|                                       EF,
  518|   392k|                                       ArgParams{{EF, _i[i], EF}, {EF, _r, EF}},
  519|   392k|                                       false,  // trailingComma
  520|   392k|                                       EF,
  521|   392k|                                       make<Conditional>(ast->location,
  522|   392k|                                                         EF,
  523|   392k|                                                         make<Binary>(E,
  524|   392k|                                                                      EF,
  525|   392k|                                                                      var(_i[i]),
  526|   392k|                                                                      EF,
  527|   392k|                                                                      BOP_GREATER_EQ,
  528|   392k|                                                                      length(var(_l))),
  529|   392k|                                                         EF,
  530|   392k|                                                         out,
  531|   392k|                                                         EF,
  532|   392k|                                                         make<Local>(
  533|   392k|                                                             ast->location,
  534|   392k|                                                             EF,
  535|   392k|                                                             singleBind(spec.var,
  536|   392k|                                                                        make<Index>(E,
  537|   392k|                                                                                    EF,
  538|   392k|                                                                                    var(_l),
  539|   392k|                                                                                    EF,
  540|   392k|                                                                                    false,
  541|   392k|                                                                                    var(_i[i]),
  542|   392k|                                                                                    EF,
  543|   392k|                                                                                    nullptr,
  544|   392k|                                                                                    EF,
  545|   392k|                                                                                    nullptr,
  546|   392k|                                                                                    EF)),
  547|   392k|                                                             in))))},
  548|   392k|                        make<Conditional>(
  549|   392k|                            ast->location,
  550|   392k|                            EF,
  551|   392k|                            equals(ast->location, type(var(_l)), str(U"array")),
  552|   392k|                            EF,
  553|   392k|                            make<Apply>(
  554|   392k|                                E,
  555|   392k|                                EF,
  556|   392k|                                var(_aux[i]),
  557|   392k|                                EF,
  558|   392k|                                ArgParams{{zero, EF},
  559|   392k|                                  {
  560|   392k|                                    i == 0 ? make<Array>(
  ------------------
  |  Branch (560:37): [True: 354k, False: 38.1k]
  ------------------
  561|   354k|                                        E, EF, Array::Elements{}, false, EF)
  562|   392k|                                        : static_cast<AST *>(var(_r)),
  563|   392k|                                        EF,
  564|   392k|                                        }},
  565|   392k|                                false,  // trailingComma
  566|   392k|                                EF,
  567|   392k|                                EF,
  568|   392k|                                true),  // tailstrict
  569|   392k|                            EF,
  570|   392k|                            error(ast->location,
  571|   392k|                                  U"In comprehension, can only iterate over array.")));
  572|   392k|                } break;
  573|   827k|            }
  574|   827k|        }
  575|       |
  576|   354k|        return in;
  577|   354k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_13LiteralNumberEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERA4_KcEEEPT_DpOT0_:
  106|   755k|    {
  107|   755k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   755k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_3VarESD_NS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  106|   354k|    {
  107|   354k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   354k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  106|   827k|    {
  107|   827k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   827k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpEPNS0_5ArrayEEEEPT_DpOT0_:
  106|   354k|    {
  107|   354k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   354k|    }
_ZN7jsonnet8internal9Desugarer9singletonEPNS0_3ASTE:
  156|   354k|    {
  157|   354k|        return make<Array>(
  158|   354k|            body->location, EF, Array::Elements{Array::Element(body, EF)}, false, EF);
  159|   354k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ArrayEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_7ElementENS9_ISE_EEEEbSD_EEEPT_DpOT0_:
  106|   354k|    {
  107|   354k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   354k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS8_INS0_8ArgParamENSA_ISH_EEEEbSE_SE_bEEEPT_DpOT0_:
  106|   865k|    {
  107|   865k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   865k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERKPNS0_3ASTESD_RSF_SD_SI_EEEPT_DpOT0_:
  106|   435k|    {
  107|   435k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   435k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISE_EEEEPNS0_11ConditionalEEEEPT_DpOT0_:
  106|   392k|    {
  107|   392k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   392k|    }
_ZN7jsonnet8internal9Desugarer4bindEPKNS0_10IdentifierEPNS0_3ASTE:
  146|  1.59M|    {
  147|  1.59M|        return Local::Bind(EF, id, EF, body, false, EF, ArgParams{}, false, EF, EF);
  148|  1.59M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_8FunctionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESD_NS7_INS0_8ArgParamENS9_ISE_EEEEbSD_PNS0_11ConditionalEEEEPT_DpOT0_:
  106|   392k|    {
  107|   392k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   392k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_6BinaryESD_RPNS0_3ASTESD_PNS0_5LocalEEEEPT_DpOT0_:
  106|   392k|    {
  107|   392k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   392k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpEPNS0_5ApplyEEEEPT_DpOT0_:
  106|   392k|    {
  107|   392k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   392k|    }
_ZN7jsonnet8internal9Desugarer6lengthEPNS0_3ASTE:
  192|   392k|    {
  193|   392k|        return stdFunc(U"length", v);
  194|   392k|    }
_ZN7jsonnet8internal9Desugarer7stdFuncERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEEPNS0_3ASTE:
  162|   789k|    {
  163|   789k|        return make<Apply>(
  164|   789k|            v->location,
  165|   789k|            EF,
  166|   789k|            make<Index>(E, EF, std(), EF, false, str(name), EF, nullptr, EF, nullptr, EF),
  167|   789k|            EF,
  168|   789k|            ArgParams{{v, EF}},
  169|   789k|            false,  // trailingComma
  170|   789k|            EF,
  171|   789k|            EF,
  172|   789k|            true  // tailstrict
  173|   789k|        );
  174|   789k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISE_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  106|   397k|    {
  107|   397k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   397k|    }
_ZN7jsonnet8internal9Desugarer10singleBindEPKNS0_10IdentifierEPNS0_3ASTE:
  151|   402k|    {
  152|   402k|        return {bind(id, body)};
  153|   402k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bSG_SE_DnSE_DnSE_EEEPT_DpOT0_:
  106|   392k|    {
  107|   392k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   392k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5ApplyESD_SF_SD_PNS0_5ErrorEEEEPT_DpOT0_:
  106|   392k|    {
  107|   392k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   392k|    }
_ZN7jsonnet8internal9Desugarer4typeEPNS0_3ASTE:
  197|   397k|    {
  198|   397k|        return stdFunc(U"type", v);
  199|   397k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ArrayEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEENS8_INS3_7ElementENSA_ISF_EEEEbSE_EEEPT_DpOT0_:
  106|   354k|    {
  107|   354k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   354k|    }
_ZN7jsonnet8internal9Desugarer5errorERKNS0_13LocationRangeERKNSt3__112basic_stringIDiNS5_11char_traitsIDiEENS5_9allocatorIDiEEEE:
  217|   392k|    {
  218|   392k|        return error(str(loc, msg));
  219|   392k|    }
_ZN7jsonnet8internal9Desugarer5errorEPNS0_3ASTE:
  212|   413k|    {
  213|   413k|        return make<Error>(msg->location, EF, msg);
  214|   413k|    }
_ZN7jsonnet8internal9Desugarer3strERKNS0_13LocationRangeERKNSt3__112basic_stringIDiNS5_11char_traitsIDiEENS5_9allocatorIDiEEEE:
  126|  2.44M|    {
  127|  2.44M|        return make<LiteralString>(loc, EF, s, LiteralString::DOUBLE, "", "");
  128|  2.44M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_13LiteralStringEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERKNS7_12basic_stringIDiNS7_11char_traitsIDiEENSA_IDiEEEENS3_9TokenKindERA1_KcSP_EEEPT_DpOT0_:
  106|  13.1M|    {
  107|  13.1M|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  13.1M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ErrorEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  106|   794k|    {
  107|   794k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   794k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_SF_SH_SF_EEEPT_DpOT0_:
  106|   380k|    {
  107|   380k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   380k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bPNS0_13LiteralStringESE_DnSE_DnSE_EEEPT_DpOT0_:
  106|  3.34M|    {
  107|  3.34M|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  3.34M|    }
_ZN7jsonnet8internal9Desugarer3stdEv:
  141|  3.34M|    {
  142|  3.34M|        return var(id(U"std"));
  143|  3.34M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_RNS7_INS0_8ArgParamENS9_ISI_EEEEbSH_SH_bEEEPT_DpOT0_:
  106|   305k|    {
  107|   305k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   305k|    }
_ZN7jsonnet8internal9Desugarer6equalsERKNS0_13LocationRangeEPNS0_3ASTES6_:
  207|  2.07M|    {
  208|  2.07M|        return stdFunc(loc, U"equals", a, b);
  209|  2.07M|    }
_ZN7jsonnet8internal9Desugarer7stdFuncERKNS0_13LocationRangeERKNSt3__112basic_stringIDiNS5_11char_traitsIDiEENS5_9allocatorIDiEEEEPNS0_3ASTESF_:
  177|  2.08M|    {
  178|  2.08M|        return make<Apply>(
  179|  2.08M|            loc,
  180|  2.08M|            EF,
  181|  2.08M|            make<Index>(E, EF, std(), EF, false, str(name), EF, nullptr, EF, nullptr, EF),
  182|  2.08M|            EF,
  183|  2.08M|            ArgParams{{a, EF}, {b, EF}},
  184|  2.08M|            false,  // trailingComma
  185|  2.08M|            EF,
  186|  2.08M|            EF,
  187|  2.08M|            true  // tailstrict
  188|  2.08M|        );
  189|  2.08M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_5IndexESE_NS8_INS0_8ArgParamENSA_ISH_EEEEbSE_SE_bEEEPT_DpOT0_:
  106|  2.08M|    {
  107|  2.08M|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  2.08M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5UnaryEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS0_7UnaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  106|   234k|    {
  107|   234k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   234k|    }
_ZN7jsonnet8internal9Desugarer4nullEv:
  131|   313k|    {
  132|   313k|        return make<LiteralNull>(E, EF);
  133|   313k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11LiteralNullEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEEEEPT_DpOT0_:
  106|   313k|    {
  107|   313k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   313k|    }
_ZN7jsonnet8internal9Desugarer3varEPKNS0_10IdentifierE:
  136|  8.77M|    {
  137|  8.77M|        return make<Var>(E, EF, ident);
  138|  8.77M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_3VarEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  106|  8.77M|    {
  107|  8.77M|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  8.77M|    }
_ZN7jsonnet8internal9Desugarer13desugarParamsERNSt3__16vectorINS0_8ArgParamENS2_9allocatorIS4_EEEEj:
  225|  3.19M|    {
  226|  4.02M|        for (auto &param : params) {
  ------------------
  |  Branch (226:26): [True: 4.02M, False: 3.19M]
  ------------------
  227|  4.02M|            if (param.expr) {
  ------------------
  |  Branch (227:17): [True: 195k, False: 3.82M]
  ------------------
  228|       |                // Default arg.
  229|   195k|                desugar(param.expr, obj_level);
  230|   195k|            }
  231|  4.02M|        }
  232|  3.19M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5IndexESD_NS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  106|   959k|    {
  107|   959k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   959k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_8FunctionEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESC_RNS7_INS0_8ArgParamENS9_ISD_EEEEbSC_RPNS0_3ASTEEEEPT_DpOT0_:
  106|   705k|    {
  107|   705k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   705k|    }
_ZN7jsonnet8internal9Desugarer10makeObjectEPNS0_6ObjectEj:
  579|   474k|    AST* makeObject(Object *ast, unsigned obj_level) {
  580|       |        // Hidden variable to allow outer/top binding.
  581|   474k|        if (obj_level == 0) {
  ------------------
  |  Branch (581:13): [True: 30.8k, False: 443k]
  ------------------
  582|  30.8k|            const Identifier *hidden_var = id(U"$");
  583|  30.8k|            auto *body = make<Self>(E, EF);
  584|  30.8k|            ast->fields.push_back(ObjectField::Local(EF, EF, hidden_var, EF, body, EF));
  585|  30.8k|        }
  586|       |
  587|   474k|        SuperVars svs = desugarFields(ast, ast->fields, obj_level);
  588|       |
  589|   474k|        DesugaredObject::Fields new_fields;
  590|   474k|        ASTs new_asserts;
  591|  2.13M|        for (const ObjectField &field : ast->fields) {
  ------------------
  |  Branch (591:39): [True: 2.13M, False: 474k]
  ------------------
  592|  2.13M|            if (field.kind == ObjectField::ASSERT) {
  ------------------
  |  Branch (592:17): [True: 21.6k, False: 2.11M]
  ------------------
  593|  21.6k|                new_asserts.push_back(field.expr2);
  594|  2.11M|            } else if (field.kind == ObjectField::FIELD_EXPR) {
  ------------------
  |  Branch (594:24): [True: 2.11M, False: 0]
  ------------------
  595|  2.11M|                new_fields.emplace_back(field.hide, field.expr1, field.expr2);
  596|  2.11M|            } else {
  597|      0|                std::cerr << "INTERNAL ERROR: field should have been desugared: " << field.kind
  598|      0|                          << std::endl;
  599|      0|            }
  600|  2.13M|        }
  601|       |
  602|   474k|        AST* retval = make<DesugaredObject>(ast->location, new_asserts, new_fields);
  603|   474k|        if (svs.size() > 0) {
  ------------------
  |  Branch (603:13): [True: 2.71k, False: 471k]
  ------------------
  604|  2.71k|            Local::Binds binds;
  605|   261k|            for (const auto &pair : svs) {
  ------------------
  |  Branch (605:35): [True: 261k, False: 2.71k]
  ------------------
  606|   261k|                if (pair.second == nullptr) {
  ------------------
  |  Branch (606:21): [True: 1.28k, False: 260k]
  ------------------
  607|       |                    // Self binding
  608|  1.28k|                    binds.push_back(bind(pair.first, make<Self>(E, EF)));
  609|   260k|                } else {
  610|       |                    // Super binding
  611|   260k|                    binds.push_back(bind(pair.first, pair.second));
  612|   260k|                }
  613|   261k|            }
  614|  2.71k|            retval = make<Local>(ast->location, EF, binds, retval);
  615|  2.71k|        }
  616|       |
  617|   474k|        return retval;
  618|   474k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_4SelfEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEEEEPT_DpOT0_:
  106|  32.2k|    {
  107|  32.2k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  32.2k|    }
_ZN7jsonnet8internal9Desugarer13desugarFieldsEPNS0_3ASTERNSt3__16vectorINS0_11ObjectFieldENS4_9allocatorIS6_EEEEj:
  239|   522k|    {
  240|       |        // Desugar children
  241|  2.28M|        for (auto &field : fields) {
  ------------------
  |  Branch (241:26): [True: 2.28M, False: 522k]
  ------------------
  242|  2.28M|            if (field.expr1 != nullptr)
  ------------------
  |  Branch (242:17): [True: 110k, False: 2.17M]
  ------------------
  243|   110k|                desugar(field.expr1, obj_level);
  244|  2.28M|            desugar(field.expr2, obj_level + 1);
  245|  2.28M|            if (field.expr3 != nullptr)
  ------------------
  |  Branch (245:17): [True: 20.2k, False: 2.26M]
  ------------------
  246|  20.2k|                desugar(field.expr3, obj_level + 1);
  247|  2.28M|            desugarParams(field.params, obj_level + 1);
  248|  2.28M|        }
  249|       |
  250|       |        // Simplify asserts
  251|  2.28M|        for (auto &field : fields) {
  ------------------
  |  Branch (251:26): [True: 2.28M, False: 522k]
  ------------------
  252|  2.28M|            if (field.kind != ObjectField::ASSERT)
  ------------------
  |  Branch (252:17): [True: 2.26M, False: 21.6k]
  ------------------
  253|  2.26M|                continue;
  254|  21.6k|            AST *msg = field.expr3;
  255|  21.6k|            field.expr3 = nullptr;
  256|  21.6k|            if (msg == nullptr) {
  ------------------
  |  Branch (256:17): [True: 1.33k, False: 20.2k]
  ------------------
  257|       |                // The location is what appears in the stacktrace.
  258|  1.33k|                msg = str(field.expr2->location, U"Object assertion failed.");
  259|  1.33k|            }
  260|       |
  261|       |            // if expr2 then true else error msg
  262|  21.6k|            field.expr2 = make<Conditional>(field.expr2->location,
  263|  21.6k|                                            EF,
  264|  21.6k|                                            field.expr2,
  265|  21.6k|                                            EF,
  266|  21.6k|                                            make<LiteralBoolean>(E, EF, true),
  267|  21.6k|                                            EF,
  268|  21.6k|                                            error(msg));
  269|  21.6k|        }
  270|       |
  271|       |        // Remove methods
  272|  2.28M|        for (auto &field : fields) {
  ------------------
  |  Branch (272:26): [True: 2.28M, False: 522k]
  ------------------
  273|  2.28M|            if (!field.methodSugar)
  ------------------
  |  Branch (273:17): [True: 1.15M, False: 1.12M]
  ------------------
  274|  1.15M|                continue;
  275|  1.12M|            field.expr2 = make<Function>(field.expr2->location,
  276|  1.12M|                                         EF,
  277|  1.12M|                                         field.fodderL,
  278|  1.12M|                                         field.params,
  279|  1.12M|                                         field.trailingComma,
  280|  1.12M|                                         field.fodderR,
  281|  1.12M|                                         field.expr2);
  282|  1.12M|            field.methodSugar = false;
  283|  1.12M|            field.params.clear();
  284|  1.12M|        }
  285|       |
  286|       |        // Remove object-level locals
  287|   522k|        auto copy = fields;
  288|   522k|        fields.clear();
  289|   522k|        Local::Binds binds;
  290|  2.28M|        for (auto &local : copy) {
  ------------------
  |  Branch (290:26): [True: 2.28M, False: 522k]
  ------------------
  291|  2.28M|            if (local.kind != ObjectField::LOCAL)
  ------------------
  |  Branch (291:17): [True: 2.18M, False: 95.9k]
  ------------------
  292|  2.18M|                continue;
  293|  95.9k|            binds.push_back(bind(local.id, local.expr2));
  294|  95.9k|        }
  295|  2.28M|        for (auto &field : copy) {
  ------------------
  |  Branch (295:26): [True: 2.28M, False: 522k]
  ------------------
  296|  2.28M|            if (field.kind == ObjectField::LOCAL)
  ------------------
  |  Branch (296:17): [True: 95.9k, False: 2.18M]
  ------------------
  297|  95.9k|                continue;
  298|  2.18M|            if (!binds.empty())
  ------------------
  |  Branch (298:17): [True: 1.15M, False: 1.03M]
  ------------------
  299|  1.15M|                field.expr2 = make<Local>(field.expr2->location, EF, binds, field.expr2);
  300|  2.18M|            fields.push_back(field);
  301|  2.18M|        }
  302|       |
  303|       |        // Change all to FIELD_EXPR
  304|  2.18M|        for (auto &field : fields) {
  ------------------
  |  Branch (304:26): [True: 2.18M, False: 522k]
  ------------------
  305|  2.18M|            switch (field.kind) {
  ------------------
  |  Branch (305:21): [True: 0, False: 2.18M]
  ------------------
  306|  21.6k|                case ObjectField::ASSERT:
  ------------------
  |  Branch (306:17): [True: 21.6k, False: 2.16M]
  ------------------
  307|       |                    // Nothing to do.
  308|  21.6k|                    break;
  309|       |
  310|  2.05M|                case ObjectField::FIELD_ID:
  ------------------
  |  Branch (310:17): [True: 2.05M, False: 132k]
  ------------------
  311|  2.05M|                    field.expr1 = str(field.idLocation, field.id->name);
  312|  2.05M|                    field.kind = ObjectField::FIELD_EXPR;
  313|  2.05M|                    break;
  314|       |
  315|  50.8k|                case ObjectField::FIELD_EXPR:
  ------------------
  |  Branch (315:17): [True: 50.8k, False: 2.13M]
  ------------------
  316|       |                    // Nothing to do.
  317|  50.8k|                    break;
  318|       |
  319|  59.6k|                case ObjectField::FIELD_STR:
  ------------------
  |  Branch (319:17): [True: 59.6k, False: 2.12M]
  ------------------
  320|       |                    // Just set the flag.
  321|  59.6k|                    field.kind = ObjectField::FIELD_EXPR;
  322|  59.6k|                    break;
  323|       |
  324|      0|                case ObjectField::LOCAL:
  ------------------
  |  Branch (324:17): [True: 0, False: 2.18M]
  ------------------
  325|      0|                    std::cerr << "Locals should be removed by now." << std::endl;
  326|      0|                    abort();
  327|  2.18M|            }
  328|  2.18M|        }
  329|       |
  330|       |        /** Replaces all occurrences of self, super[f] and e in super with variables.
  331|       |         *
  332|       |         * Returns all variables and original expressions via super_vars.
  333|       |         */
  334|   522k|        class SubstituteSelfSuper : public CompilerPass {
  335|   522k|            Desugarer *desugarer;
  336|   522k|            SuperVars &superVars;
  337|   522k|            unsigned &counter;
  338|   522k|            const Identifier *newSelf;
  339|       |
  340|   522k|           public:
  341|   522k|            SubstituteSelfSuper(Desugarer *desugarer, SuperVars &super_vars, unsigned &counter)
  342|   522k|                : CompilerPass(*desugarer->alloc),
  343|   522k|                  desugarer(desugarer),
  344|   522k|                  superVars(super_vars),
  345|   522k|                  counter(counter),
  346|   522k|                  newSelf(nullptr)
  347|   522k|            {
  348|   522k|            }
  349|   522k|            void visitExpr(AST *&expr)
  350|   522k|            {
  351|   522k|                if (dynamic_cast<Self *>(expr)) {
  352|   522k|                    if (newSelf == nullptr) {
  353|   522k|                        newSelf = desugarer->id(U"$outer_self");
  354|   522k|                        superVars.emplace_back(newSelf, nullptr);
  355|   522k|                    }
  356|   522k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, newSelf);
  357|   522k|                } else if (auto *super_index = dynamic_cast<SuperIndex *>(expr)) {
  358|   522k|                    UStringStream ss;
  359|   522k|                    ss << U"$outer_super_index" << (counter++);
  360|   522k|                    const Identifier *super_var = desugarer->id(ss.str());
  361|       |                    // Desugaring of expr should already have occurred.
  362|   522k|                    assert(super_index->index != nullptr);
  363|       |                    // Re-use super_index since we're replacing it here.
  364|   522k|                    superVars.emplace_back(super_var, super_index);
  365|   522k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, super_var);
  366|   522k|                } else if (auto *in_super = dynamic_cast<InSuper *>(expr)) {
  367|   522k|                    UStringStream ss;
  368|   522k|                    ss << U"$outer_in_super" << (counter++);
  369|   522k|                    const Identifier *in_super_var = desugarer->id(ss.str());
  370|       |                    // Re-use in_super since we're replacing it here.
  371|   522k|                    superVars.emplace_back(in_super_var, in_super);
  372|   522k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, in_super_var);
  373|   522k|                }
  374|   522k|                CompilerPass::visitExpr(expr);
  375|   522k|            }
  376|   522k|        };
  377|       |
  378|   522k|        SuperVars super_vars;
  379|   522k|        unsigned counter = 0;
  380|       |
  381|       |        // Remove +:
  382|  2.18M|        for (auto &field : fields) {
  ------------------
  |  Branch (382:26): [True: 2.18M, False: 522k]
  ------------------
  383|  2.18M|            if (!field.superSugar)
  ------------------
  |  Branch (383:17): [True: 2.17M, False: 16.5k]
  ------------------
  384|  2.17M|                continue;
  385|       |            // We have to bind self/super from expr1 outside the class, as we copy the expression
  386|       |            // into the field body.
  387|       |            // Clone it so that we maintain the AST as a tree.
  388|  16.5k|            AST *index = clone(field.expr1);
  389|       |            // This will remove self/super.
  390|  16.5k|            SubstituteSelfSuper(this, super_vars, counter).expr(index);
  391|  16.5k|            field.expr2 = make<Conditional>(
  392|  16.5k|                ast->location,
  393|  16.5k|                EF,
  394|  16.5k|                make<InSuper>(ast->location, EF, index, EF, EF),
  395|  16.5k|                EF,
  396|  16.5k|                make<Binary>(ast->location,
  397|  16.5k|                             EF,
  398|  16.5k|                             make<SuperIndex>(ast->location, EF, EF, clone(index), EF, nullptr),
  399|  16.5k|                             EF,
  400|  16.5k|                             BOP_PLUS,
  401|  16.5k|                             field.expr2),
  402|  16.5k|                EF,
  403|  16.5k|                clone(field.expr2));
  404|  16.5k|            field.superSugar = false;
  405|  16.5k|        }
  406|       |
  407|   522k|        return super_vars;
  408|   522k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTESD_PNS0_14LiteralBooleanESD_PNS0_5ErrorEEEEPT_DpOT0_:
  106|  21.6k|    {
  107|  21.6k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  21.6k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_14LiteralBooleanEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEbEEEPT_DpOT0_:
  106|  21.6k|    {
  107|  21.6k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  21.6k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_8FunctionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERSB_RNS7_INS0_8ArgParamENS9_ISF_EEEERbSE_RPNS0_3ASTEEEEPT_DpOT0_:
  106|  1.12M|    {
  107|  1.12M|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  1.12M|    }
_ZN7jsonnet8internal9Desugarer5cloneEPNS0_3ASTE:
  111|  49.7k|    {
  112|  49.7k|        return clone_ast(*alloc, ast);
  113|  49.7k|    }
_ZZN7jsonnet8internal9Desugarer13desugarFieldsEPNS0_3ASTERNSt3__16vectorINS0_11ObjectFieldENS4_9allocatorIS6_EEEEjEN19SubstituteSelfSuperC2EPS1_RNS5_INS4_4pairIPKNS0_10IdentifierES3_EENS7_ISH_EEEERj:
  347|  16.5k|            {
  348|  16.5k|            }
_ZZN7jsonnet8internal9Desugarer13desugarFieldsEPNS0_3ASTERNSt3__16vectorINS0_11ObjectFieldENS4_9allocatorIS6_EEEEjEN19SubstituteSelfSuper9visitExprERS3_:
  350|  2.71M|            {
  351|  2.71M|                if (dynamic_cast<Self *>(expr)) {
  ------------------
  |  Branch (351:21): [True: 7.73k, False: 2.70M]
  ------------------
  352|  7.73k|                    if (newSelf == nullptr) {
  ------------------
  |  Branch (352:25): [True: 1.29k, False: 6.43k]
  ------------------
  353|  1.29k|                        newSelf = desugarer->id(U"$outer_self");
  354|  1.29k|                        superVars.emplace_back(newSelf, nullptr);
  355|  1.29k|                    }
  356|  7.73k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, newSelf);
  357|  2.70M|                } else if (auto *super_index = dynamic_cast<SuperIndex *>(expr)) {
  ------------------
  |  Branch (357:34): [True: 147k, False: 2.55M]
  ------------------
  358|   147k|                    UStringStream ss;
  359|   147k|                    ss << U"$outer_super_index" << (counter++);
  360|   147k|                    const Identifier *super_var = desugarer->id(ss.str());
  361|       |                    // Desugaring of expr should already have occurred.
  362|   147k|                    assert(super_index->index != nullptr);
  363|       |                    // Re-use super_index since we're replacing it here.
  364|      0|                    superVars.emplace_back(super_var, super_index);
  365|   147k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, super_var);
  366|  2.55M|                } else if (auto *in_super = dynamic_cast<InSuper *>(expr)) {
  ------------------
  |  Branch (366:34): [True: 124k, False: 2.43M]
  ------------------
  367|   124k|                    UStringStream ss;
  368|   124k|                    ss << U"$outer_in_super" << (counter++);
  369|   124k|                    const Identifier *in_super_var = desugarer->id(ss.str());
  370|       |                    // Re-use in_super since we're replacing it here.
  371|   124k|                    superVars.emplace_back(in_super_var, in_super);
  372|   124k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, in_super_var);
  373|   124k|                }
  374|      0|                CompilerPass::visitExpr(expr);
  375|  2.71M|            }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_7InSuperESD_PNS0_6BinaryESD_PNS0_3ASTEEEEPT_DpOT0_:
  106|  16.5k|    {
  107|  16.5k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  16.5k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_7InSuperEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTESD_SD_EEEPT_DpOT0_:
  106|  16.5k|    {
  107|  16.5k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  16.5k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_6BinaryEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_10SuperIndexESD_NS0_8BinaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  106|  16.5k|    {
  107|  16.5k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  16.5k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_10SuperIndexEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESD_PNS0_3ASTESD_DnEEEPT_DpOT0_:
  106|  16.5k|    {
  107|  16.5k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  16.5k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_15DesugaredObjectEJRNS0_13LocationRangeERNSt3__14listIPNS0_3ASTENS6_9allocatorIS9_EEEERNS6_6vectorINS3_5FieldENSA_ISF_EEEEEEEPT_DpOT0_:
  106|   474k|    {
  107|   474k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   474k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERNS7_INS3_4BindENS9_ISE_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  106|  1.20M|    {
  107|  1.20M|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  1.20M|    }
_ZN7jsonnet8internal9Desugarer23makeObjectComprehensionEPNS0_19ObjectComprehensionEj:
  620|  47.4k|    AST* makeObjectComprehension(ObjectComprehension *ast, unsigned obj_level) {
  621|       |        // Hidden variable to allow outer/top binding.
  622|  47.4k|        if (obj_level == 0) {
  ------------------
  |  Branch (622:13): [True: 119, False: 47.3k]
  ------------------
  623|    119|            const Identifier *hidden_var = id(U"$");
  624|    119|            auto *body = make<Self>(E, EF);
  625|    119|            ast->fields.push_back(ObjectField::Local(EF, EF, hidden_var, EF, body, EF));
  626|    119|        }
  627|       |
  628|  47.4k|        SuperVars svs = desugarFields(ast, ast->fields, obj_level);
  629|       |
  630|  47.4k|        AST *field = ast->fields.front().expr1;
  631|  47.4k|        AST *value = ast->fields.front().expr2;
  632|       |
  633|       |        /*  {
  634|       |            [arr[0]]: local x = arr[1], y = arr[2], z = arr[3]; val_expr
  635|       |            for arr in [ [key_expr, x, y, z] for ...  ]
  636|       |            }
  637|       |        */
  638|  47.4k|        auto *_arr = id(U"$arr");
  639|  47.4k|        AST *zero = make<LiteralNumber>(E, EF, "0.0");
  640|  47.4k|        int counter = 1;
  641|  47.4k|        Local::Binds binds;
  642|  47.4k|        Array::Elements arr_e{Array::Element(field, EF)};
  643|  76.3k|        for (ComprehensionSpec &spec : ast->specs) {
  ------------------
  |  Branch (643:38): [True: 76.3k, False: 47.4k]
  ------------------
  644|  76.3k|            if (spec.kind == ComprehensionSpec::FOR) {
  ------------------
  |  Branch (644:17): [True: 54.6k, False: 21.7k]
  ------------------
  645|  54.6k|                std::stringstream num;
  646|  54.6k|                num << counter++;
  647|  54.6k|                binds.push_back(bind(spec.var,
  648|  54.6k|                                     make<Index>(E,
  649|  54.6k|                                                 EF,
  650|  54.6k|                                                 var(_arr),
  651|  54.6k|                                                 EF,
  652|  54.6k|                                                 false,
  653|  54.6k|                                                 make<LiteralNumber>(E, EF, num.str()),
  654|  54.6k|                                                 EF,
  655|  54.6k|                                                 nullptr,
  656|  54.6k|                                                 EF,
  657|  54.6k|                                                 nullptr,
  658|  54.6k|                                                 EF)));
  659|  54.6k|                arr_e.emplace_back(var(spec.var), EF);
  660|  54.6k|            }
  661|  76.3k|        }
  662|  47.4k|        AST *arr = make<ArrayComprehension>(ast->location,
  663|  47.4k|                                            EF,
  664|  47.4k|                                            make<Array>(ast->location, EF, arr_e, false, EF),
  665|  47.4k|                                            EF,
  666|  47.4k|                                            false,
  667|  47.4k|                                            ast->specs,
  668|  47.4k|                                            EF);
  669|  47.4k|        desugar(arr, obj_level);
  670|  47.4k|        return make<ObjectComprehensionSimple>(
  671|  47.4k|            ast->location,
  672|  47.4k|            make<Index>(E, EF, var(_arr), EF, false, zero, EF, nullptr, EF, nullptr, EF),
  673|  47.4k|            make<Local>(ast->location, EF, binds, value),
  674|  47.4k|            _arr,
  675|  47.4k|            arr);
  676|  47.4k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bPNS0_13LiteralNumberESE_DnSE_DnSE_EEEPT_DpOT0_:
  106|  54.6k|    {
  107|  54.6k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  54.6k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_13LiteralNumberEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEENS7_12basic_stringIcNS7_11char_traitsIcEENSA_IcEEEEEEEPT_DpOT0_:
  106|  54.6k|    {
  107|  54.6k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  54.6k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_18ArrayComprehensionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5ArrayESD_bRNS7_INS0_17ComprehensionSpecENS9_ISG_EEEESD_EEEPT_DpOT0_:
  106|  47.4k|    {
  107|  47.4k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  47.4k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ArrayEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERNS7_INS3_7ElementENS9_ISE_EEEEbSD_EEEPT_DpOT0_:
  106|  47.4k|    {
  107|  47.4k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  47.4k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_25ObjectComprehensionSimpleEJRNS0_13LocationRangeEPNS0_5IndexEPNS0_5LocalERPKNS0_10IdentifierERPNS0_3ASTEEEEPT_DpOT0_:
  106|  47.4k|    {
  107|  47.4k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  47.4k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bRPNS0_3ASTESE_DnSE_DnSE_EEEPT_DpOT0_:
  106|  47.4k|    {
  107|  47.4k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  47.4k|    }
_ZN7jsonnet8internal9Desugarer2idERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEE:
  116|  6.62M|    {
  117|  6.62M|        return alloc->makeIdentifier(s);
  118|  6.62M|    }
_ZN7jsonnet8internal9Desugarer3strERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEE:
  121|  10.7M|    {
  122|  10.7M|        return make<LiteralString>(E, EF, s, LiteralString::DOUBLE, "", "");
  123|  10.7M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_15BuiltinFunctionEJRKNS0_13LocationRangeENSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEERNS7_6vectorIPKNS0_10IdentifierENSB_ISH_EEEEEEEPT_DpOT0_:
  106|   361k|    {
  107|   361k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|   361k|    }
_ZZN7jsonnet8internal9Desugarer9stdlibASTENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEENKUlRKNS0_15DesugaredObject5FieldEE_clESC_:
  934|  41.6M|                [=](const DesugaredObject::Field& f) {
  935|  41.6M|                    return static_cast<LiteralString*>(f.name)->value == decl.name;
  936|  41.6M|                });
_ZN7jsonnet8internal9Desugarer11desugarFileERPNS0_3ASTEPNSt3__13mapINS5_12basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEENS0_5VmExtENS5_4lessISC_EENSA_INS5_4pairIKSC_SD_EEEEEE:
  949|  5.70k|    {
  950|  5.70k|        desugar(ast, 0);
  951|       |
  952|  5.70k|        DesugaredObject *std_obj = stdlibAST(ast->location.file);
  953|       |
  954|  5.70k|        std::vector<std::string> empty;
  955|  5.70k|        auto line_end_blank = Fodder{{FodderElement::LINE_END, 1, 0, empty}};
  956|  5.70k|        auto line_end = Fodder{{FodderElement::LINE_END, 0, 0, empty}};
  957|       |
  958|       |        // local body = ast;
  959|       |        // if std.type(body) == "function") then
  960|       |        //     body(tlas...)
  961|       |        // else
  962|       |        //     body
  963|  5.70k|        if (tlas != nullptr) {
  ------------------
  |  Branch (963:13): [True: 5.11k, False: 594]
  ------------------
  964|  5.11k|            LocationRange tla_loc("Top-level function");
  965|  5.11k|            ArgParams args;
  966|  5.11k|            for (const auto &pair : *tlas) {
  ------------------
  |  Branch (966:35): [True: 0, False: 5.11k]
  ------------------
  967|      0|                AST *expr;
  968|      0|                if (pair.second.isCode) {
  ------------------
  |  Branch (968:21): [True: 0, False: 0]
  ------------------
  969|      0|                    Tokens tokens = jsonnet_lex("tla:" + pair.first, pair.second.data.c_str());
  970|      0|                    expr = jsonnet_parse(alloc, tokens);
  971|      0|                    desugar(expr, 0);
  972|      0|                } else {
  973|      0|                    expr = str(decode_utf8(pair.second.data));
  974|      0|                }
  975|       |                // Add them as named arguments, so order does not matter.
  976|      0|                args.emplace_back(EF, id(decode_utf8(pair.first)), EF, expr, EF);
  977|      0|            }
  978|  5.11k|            const Identifier *body = id(U"top_level");
  979|  5.11k|            ast =
  980|  5.11k|                make<Local>(ast->location,
  981|  5.11k|                            line_end_blank,
  982|  5.11k|                            singleBind(body, ast),
  983|  5.11k|                            make<Conditional>(E,
  984|  5.11k|                                              line_end,
  985|  5.11k|                                              primitiveEquals(E, type(var(body)), str(U"function")),
  986|  5.11k|                                              EF,
  987|  5.11k|                                              make<Apply>(tla_loc,
  988|  5.11k|                                                          EF,
  989|  5.11k|                                                          make<Var>(E, line_end, body),
  990|  5.11k|                                                          EF,
  991|  5.11k|                                                          args,
  992|  5.11k|                                                          false,  // trailing comma
  993|  5.11k|                                                          EF,
  994|  5.11k|                                                          EF,
  995|  5.11k|                                                          false  // tailstrict
  996|  5.11k|                                                          ),
  997|  5.11k|                                              line_end,
  998|  5.11k|                                              make<Var>(E, line_end, body)));
  999|  5.11k|        }
 1000|       |
 1001|       |        // local std = (std.jsonnet stuff); ast
 1002|  5.70k|        ast = make<Local>(ast->location, EF, singleBind(id(U"std"), std_obj), ast);
 1003|  5.70k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5LocalEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISD_EEEEPNS0_11ConditionalEEEEPT_DpOT0_:
  106|  5.11k|    {
  107|  5.11k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  5.11k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRKNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_5ApplyERKSC_SF_SD_PNS0_3VarEEEEPT_DpOT0_:
  106|  5.11k|    {
  107|  5.11k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  5.11k|    }
_ZN7jsonnet8internal9Desugarer15primitiveEqualsERKNS0_13LocationRangeEPNS0_3ASTES6_:
  202|  5.11k|    {
  203|  5.11k|        return stdFunc(loc, U"primitiveEquals", a, b);
  204|  5.11k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_3VarESD_RNS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  106|  5.11k|    {
  107|  5.11k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  5.11k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_3VarEJRKNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  106|  10.2k|    {
  107|  10.2k|        return alloc->make<T>(std::forward<Args>(args)...);
  108|  10.2k|    }

_ZN7jsonnet8internal7FmtOptsC2Ev:
   48|  9.27k|    {
   49|  9.27k|    }

_ZN7jsonnet8internal26allowed_at_end_of_operatorEc:
  174|  12.6M|bool allowed_at_end_of_operator(char c) {
  175|  12.6M|    switch (c) {
  ------------------
  |  Branch (175:13): [True: 3.94M, False: 8.73M]
  ------------------
  176|  8.18M|        case '+':
  ------------------
  |  Branch (176:9): [True: 8.18M, False: 4.49M]
  ------------------
  177|  8.44M|        case '-':
  ------------------
  |  Branch (177:9): [True: 259k, False: 12.4M]
  ------------------
  178|  8.48M|        case '~':
  ------------------
  |  Branch (178:9): [True: 38.3k, False: 12.6M]
  ------------------
  179|  8.59M|        case '!':
  ------------------
  |  Branch (179:9): [True: 107k, False: 12.5M]
  ------------------
  180|  8.73M|        case '$': return false;
  ------------------
  |  Branch (180:9): [True: 145k, False: 12.5M]
  ------------------
  181|  12.6M|    }
  182|  3.94M|    return true;
  183|  12.6M|}
_ZN7jsonnet8internal20lex_get_keyword_kindERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  207|  55.8M|{
  208|  55.8M|    auto it = keywords.find(identifier);
  209|  55.8M|    if (it == keywords.end())
  ------------------
  |  Branch (209:9): [True: 40.7M, False: 15.0M]
  ------------------
  210|  40.7M|        return Token::IDENTIFIER;
  211|  15.0M|    return it->second;
  212|  55.8M|}
_ZN7jsonnet8internal10lex_numberERPKcRKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEERKNS0_8LocationE:
  215|  7.35M|{
  216|       |    // This function should be understood with reference to the linked image:
  217|       |    // https://www.json.org/img/number.png
  218|       |
  219|       |    // Note, we deviate from the json.org documentation as follows:
  220|       |    // There is no reason to lex negative numbers as atomic tokens, it is better to parse them
  221|       |    // as a unary operator combined with a numeric literal.  This avoids x-1 being tokenized as
  222|       |    // <identifier> <number> instead of the intended <identifier> <binop> <number>.
  223|       |
  224|  7.35M|    enum State {
  225|  7.35M|        BEGIN,
  226|  7.35M|        AFTER_ZERO,
  227|  7.35M|        AFTER_ONE_TO_NINE,
  228|  7.35M|        AFTER_DOT,
  229|  7.35M|        AFTER_DIGIT,
  230|  7.35M|        AFTER_E,
  231|  7.35M|        AFTER_EXP_SIGN,
  232|  7.35M|        AFTER_EXP_DIGIT
  233|  7.35M|    } state;
  234|       |
  235|  7.35M|    std::string r;
  236|       |
  237|  7.35M|    state = BEGIN;
  238|  15.7M|    while (true) {
  ------------------
  |  Branch (238:12): [Folded - Ignored]
  ------------------
  239|  15.7M|        switch (state) {
  ------------------
  |  Branch (239:17): [True: 0, False: 15.7M]
  ------------------
  240|  7.35M|            case BEGIN:
  ------------------
  |  Branch (240:13): [True: 7.35M, False: 8.36M]
  ------------------
  241|  7.35M|                switch (*c) {
  242|  1.55M|                    case '0': state = AFTER_ZERO; break;
  ------------------
  |  Branch (242:21): [True: 1.55M, False: 5.80M]
  ------------------
  243|       |
  244|  1.60M|                    case '1':
  ------------------
  |  Branch (244:21): [True: 1.60M, False: 5.75M]
  ------------------
  245|  1.92M|                    case '2':
  ------------------
  |  Branch (245:21): [True: 323k, False: 7.03M]
  ------------------
  246|  2.58M|                    case '3':
  ------------------
  |  Branch (246:21): [True: 654k, False: 6.70M]
  ------------------
  247|  2.73M|                    case '4':
  ------------------
  |  Branch (247:21): [True: 151k, False: 7.20M]
  ------------------
  248|  2.75M|                    case '5':
  ------------------
  |  Branch (248:21): [True: 25.3k, False: 7.33M]
  ------------------
  249|  4.31M|                    case '6':
  ------------------
  |  Branch (249:21): [True: 1.55M, False: 5.80M]
  ------------------
  250|  4.44M|                    case '7':
  ------------------
  |  Branch (250:21): [True: 132k, False: 7.22M]
  ------------------
  251|  4.90M|                    case '8':
  ------------------
  |  Branch (251:21): [True: 457k, False: 6.89M]
  ------------------
  252|  5.80M|                    case '9': state = AFTER_ONE_TO_NINE; break;
  ------------------
  |  Branch (252:21): [True: 904k, False: 6.45M]
  ------------------
  253|       |
  254|      0|                    default: throw StaticError(filename, begin, "couldn't lex number");
  ------------------
  |  Branch (254:21): [True: 0, False: 7.35M]
  ------------------
  255|  7.35M|                }
  256|  7.35M|                break;
  257|       |
  258|  7.35M|            case AFTER_ZERO:
  ------------------
  |  Branch (258:13): [True: 1.55M, False: 14.1M]
  ------------------
  259|  1.55M|                switch (*c) {
  260|  19.8k|                    case '.': state = AFTER_DOT; break;
  ------------------
  |  Branch (260:21): [True: 19.8k, False: 1.53M]
  ------------------
  261|       |
  262|  3.18k|                    case 'e':
  ------------------
  |  Branch (262:21): [True: 3.18k, False: 1.54M]
  ------------------
  263|  5.33k|                    case 'E': state = AFTER_E; break;
  ------------------
  |  Branch (263:21): [True: 2.14k, False: 1.54M]
  ------------------
  264|       |
  265|  1.52M|                    default: goto end;
  ------------------
  |  Branch (265:21): [True: 1.52M, False: 25.1k]
  ------------------
  266|  1.55M|                }
  267|  25.1k|                break;
  268|       |
  269|  6.72M|            case AFTER_ONE_TO_NINE:
  ------------------
  |  Branch (269:13): [True: 6.72M, False: 8.99M]
  ------------------
  270|  6.72M|                switch (*c) {
  271|  3.74k|                    case '.': state = AFTER_DOT; break;
  ------------------
  |  Branch (271:21): [True: 3.74k, False: 6.72M]
  ------------------
  272|       |
  273|  2.45k|                    case 'e':
  ------------------
  |  Branch (273:21): [True: 2.45k, False: 6.72M]
  ------------------
  274|  2.85k|                    case 'E': state = AFTER_E; break;
  ------------------
  |  Branch (274:21): [True: 406, False: 6.72M]
  ------------------
  275|       |
  276|   485k|                    case '0':
  ------------------
  |  Branch (276:21): [True: 485k, False: 6.24M]
  ------------------
  277|   505k|                    case '1':
  ------------------
  |  Branch (277:21): [True: 20.4k, False: 6.70M]
  ------------------
  278|   621k|                    case '2':
  ------------------
  |  Branch (278:21): [True: 115k, False: 6.61M]
  ------------------
  279|   658k|                    case '3':
  ------------------
  |  Branch (279:21): [True: 36.8k, False: 6.69M]
  ------------------
  280|   698k|                    case '4':
  ------------------
  |  Branch (280:21): [True: 40.8k, False: 6.68M]
  ------------------
  281|   794k|                    case '5':
  ------------------
  |  Branch (281:21): [True: 95.5k, False: 6.63M]
  ------------------
  282|   855k|                    case '6':
  ------------------
  |  Branch (282:21): [True: 60.7k, False: 6.66M]
  ------------------
  283|   885k|                    case '7':
  ------------------
  |  Branch (283:21): [True: 30.5k, False: 6.69M]
  ------------------
  284|   896k|                    case '8':
  ------------------
  |  Branch (284:21): [True: 10.6k, False: 6.71M]
  ------------------
  285|   922k|                    case '9': state = AFTER_ONE_TO_NINE; break;
  ------------------
  |  Branch (285:21): [True: 26.4k, False: 6.70M]
  ------------------
  286|       |
  287|  5.79M|                    default: goto end;
  ------------------
  |  Branch (287:21): [True: 5.79M, False: 929k]
  ------------------
  288|  6.72M|                }
  289|   929k|                break;
  290|       |
  291|   929k|            case AFTER_DOT:
  ------------------
  |  Branch (291:13): [True: 23.5k, False: 15.7M]
  ------------------
  292|  23.5k|                switch (*c) {
  293|    529|                    case '0':
  ------------------
  |  Branch (293:21): [True: 529, False: 23.0k]
  ------------------
  294|    687|                    case '1':
  ------------------
  |  Branch (294:21): [True: 158, False: 23.4k]
  ------------------
  295|    727|                    case '2':
  ------------------
  |  Branch (295:21): [True: 40, False: 23.5k]
  ------------------
  296|  2.27k|                    case '3':
  ------------------
  |  Branch (296:21): [True: 1.54k, False: 22.0k]
  ------------------
  297|  3.28k|                    case '4':
  ------------------
  |  Branch (297:21): [True: 1.01k, False: 22.5k]
  ------------------
  298|  21.9k|                    case '5':
  ------------------
  |  Branch (298:21): [True: 18.6k, False: 4.98k]
  ------------------
  299|  22.2k|                    case '6':
  ------------------
  |  Branch (299:21): [True: 366, False: 23.2k]
  ------------------
  300|  22.2k|                    case '7':
  ------------------
  |  Branch (300:21): [True: 11, False: 23.5k]
  ------------------
  301|  23.5k|                    case '8':
  ------------------
  |  Branch (301:21): [True: 1.28k, False: 22.3k]
  ------------------
  302|  23.5k|                    case '9': state = AFTER_DIGIT; break;
  ------------------
  |  Branch (302:21): [True: 17, False: 23.5k]
  ------------------
  303|       |
  304|     19|                    default: {
  ------------------
  |  Branch (304:21): [True: 19, False: 23.5k]
  ------------------
  305|     19|                        std::stringstream ss;
  306|     19|                        ss << "couldn't lex number, junk after decimal point: " << *c;
  307|     19|                        throw StaticError(filename, begin, ss.str());
  308|  23.5k|                    }
  309|  23.5k|                }
  310|  23.5k|                break;
  311|       |
  312|  36.9k|            case AFTER_DIGIT:
  ------------------
  |  Branch (312:13): [True: 36.9k, False: 15.6M]
  ------------------
  313|  36.9k|                switch (*c) {
  314|    195|                    case 'e':
  ------------------
  |  Branch (314:21): [True: 195, False: 36.7k]
  ------------------
  315|    519|                    case 'E': state = AFTER_E; break;
  ------------------
  |  Branch (315:21): [True: 324, False: 36.6k]
  ------------------
  316|       |
  317|  3.75k|                    case '0':
  ------------------
  |  Branch (317:21): [True: 3.75k, False: 33.1k]
  ------------------
  318|  5.89k|                    case '1':
  ------------------
  |  Branch (318:21): [True: 2.13k, False: 34.8k]
  ------------------
  319|  6.28k|                    case '2':
  ------------------
  |  Branch (319:21): [True: 398, False: 36.5k]
  ------------------
  320|  8.53k|                    case '3':
  ------------------
  |  Branch (320:21): [True: 2.24k, False: 34.6k]
  ------------------
  321|  9.14k|                    case '4':
  ------------------
  |  Branch (321:21): [True: 612, False: 36.3k]
  ------------------
  322|  10.0k|                    case '5':
  ------------------
  |  Branch (322:21): [True: 954, False: 35.9k]
  ------------------
  323|  11.2k|                    case '6':
  ------------------
  |  Branch (323:21): [True: 1.11k, False: 35.8k]
  ------------------
  324|  11.6k|                    case '7':
  ------------------
  |  Branch (324:21): [True: 482, False: 36.4k]
  ------------------
  325|  12.2k|                    case '8':
  ------------------
  |  Branch (325:21): [True: 575, False: 36.3k]
  ------------------
  326|  13.3k|                    case '9': state = AFTER_DIGIT; break;
  ------------------
  |  Branch (326:21): [True: 1.09k, False: 35.8k]
  ------------------
  327|       |
  328|  23.0k|                    default: goto end;
  ------------------
  |  Branch (328:21): [True: 23.0k, False: 13.8k]
  ------------------
  329|  36.9k|                }
  330|  13.8k|                break;
  331|       |
  332|  13.8k|            case AFTER_E:
  ------------------
  |  Branch (332:13): [True: 8.71k, False: 15.7M]
  ------------------
  333|  8.71k|                switch (*c) {
  334|    353|                    case '+':
  ------------------
  |  Branch (334:21): [True: 353, False: 8.35k]
  ------------------
  335|  1.77k|                    case '-': state = AFTER_EXP_SIGN; break;
  ------------------
  |  Branch (335:21): [True: 1.42k, False: 7.28k]
  ------------------
  336|       |
  337|     96|                    case '0':
  ------------------
  |  Branch (337:21): [True: 96, False: 8.61k]
  ------------------
  338|  2.68k|                    case '1':
  ------------------
  |  Branch (338:21): [True: 2.59k, False: 6.12k]
  ------------------
  339|  5.20k|                    case '2':
  ------------------
  |  Branch (339:21): [True: 2.52k, False: 6.18k]
  ------------------
  340|  5.37k|                    case '3':
  ------------------
  |  Branch (340:21): [True: 164, False: 8.54k]
  ------------------
  341|  5.53k|                    case '4':
  ------------------
  |  Branch (341:21): [True: 164, False: 8.54k]
  ------------------
  342|  5.80k|                    case '5':
  ------------------
  |  Branch (342:21): [True: 272, False: 8.43k]
  ------------------
  343|  6.14k|                    case '6':
  ------------------
  |  Branch (343:21): [True: 336, False: 8.37k]
  ------------------
  344|  6.28k|                    case '7':
  ------------------
  |  Branch (344:21): [True: 141, False: 8.57k]
  ------------------
  345|  6.71k|                    case '8':
  ------------------
  |  Branch (345:21): [True: 432, False: 8.27k]
  ------------------
  346|  6.90k|                    case '9': state = AFTER_EXP_DIGIT; break;
  ------------------
  |  Branch (346:21): [True: 187, False: 8.52k]
  ------------------
  347|       |
  348|     30|                    default: {
  ------------------
  |  Branch (348:21): [True: 30, False: 8.68k]
  ------------------
  349|     30|                        std::stringstream ss;
  350|     30|                        ss << "couldn't lex number, junk after 'E': " << *c;
  351|     30|                        throw StaticError(filename, begin, ss.str());
  352|  6.71k|                    }
  353|  8.71k|                }
  354|  8.68k|                break;
  355|       |
  356|  8.68k|            case AFTER_EXP_SIGN:
  ------------------
  |  Branch (356:13): [True: 1.77k, False: 15.7M]
  ------------------
  357|  1.77k|                switch (*c) {
  358|  1.00k|                    case '0':
  ------------------
  |  Branch (358:21): [True: 1.00k, False: 773]
  ------------------
  359|  1.34k|                    case '1':
  ------------------
  |  Branch (359:21): [True: 340, False: 1.43k]
  ------------------
  360|  1.69k|                    case '2':
  ------------------
  |  Branch (360:21): [True: 346, False: 1.43k]
  ------------------
  361|  1.74k|                    case '3':
  ------------------
  |  Branch (361:21): [True: 59, False: 1.71k]
  ------------------
  362|  1.75k|                    case '4':
  ------------------
  |  Branch (362:21): [True: 3, False: 1.77k]
  ------------------
  363|  1.75k|                    case '5':
  ------------------
  |  Branch (363:21): [True: 2, False: 1.77k]
  ------------------
  364|  1.75k|                    case '6':
  ------------------
  |  Branch (364:21): [True: 3, False: 1.77k]
  ------------------
  365|  1.75k|                    case '7':
  ------------------
  |  Branch (365:21): [True: 1, False: 1.77k]
  ------------------
  366|  1.76k|                    case '8':
  ------------------
  |  Branch (366:21): [True: 6, False: 1.77k]
  ------------------
  367|  1.76k|                    case '9': state = AFTER_EXP_DIGIT; break;
  ------------------
  |  Branch (367:21): [True: 2, False: 1.77k]
  ------------------
  368|       |
  369|     11|                    default: {
  ------------------
  |  Branch (369:21): [True: 11, False: 1.76k]
  ------------------
  370|     11|                        std::stringstream ss;
  371|     11|                        ss << "couldn't lex number, junk after exponent sign: " << *c;
  372|     11|                        throw StaticError(filename, begin, ss.str());
  373|  1.76k|                    }
  374|  1.77k|                }
  375|  1.76k|                break;
  376|       |
  377|  17.5k|            case AFTER_EXP_DIGIT:
  ------------------
  |  Branch (377:13): [True: 17.5k, False: 15.7M]
  ------------------
  378|  17.5k|                switch (*c) {
  379|  2.15k|                    case '0':
  ------------------
  |  Branch (379:21): [True: 2.15k, False: 15.3k]
  ------------------
  380|  2.39k|                    case '1':
  ------------------
  |  Branch (380:21): [True: 244, False: 17.2k]
  ------------------
  381|  3.64k|                    case '2':
  ------------------
  |  Branch (381:21): [True: 1.25k, False: 16.2k]
  ------------------
  382|  3.73k|                    case '3':
  ------------------
  |  Branch (382:21): [True: 90, False: 17.4k]
  ------------------
  383|  4.86k|                    case '4':
  ------------------
  |  Branch (383:21): [True: 1.13k, False: 16.3k]
  ------------------
  384|  6.36k|                    case '5':
  ------------------
  |  Branch (384:21): [True: 1.49k, False: 16.0k]
  ------------------
  385|  6.73k|                    case '6':
  ------------------
  |  Branch (385:21): [True: 364, False: 17.1k]
  ------------------
  386|  8.73k|                    case '7':
  ------------------
  |  Branch (386:21): [True: 2.00k, False: 15.5k]
  ------------------
  387|  8.80k|                    case '8':
  ------------------
  |  Branch (387:21): [True: 67, False: 17.4k]
  ------------------
  388|  8.85k|                    case '9': state = AFTER_EXP_DIGIT; break;
  ------------------
  |  Branch (388:21): [True: 56, False: 17.4k]
  ------------------
  389|       |
  390|  8.67k|                    default: goto end;
  ------------------
  |  Branch (390:21): [True: 8.67k, False: 8.85k]
  ------------------
  391|  17.5k|                }
  392|  8.85k|                break;
  393|  15.7M|        }
  394|  8.36M|        r += *c;
  395|  8.36M|        c++;
  396|  8.36M|    }
  397|  7.35M|end:
  398|  7.35M|    return r;
  399|  7.35M|}
_ZN7jsonnet8internal11jsonnet_lexERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPKc:
  427|  18.5k|{
  428|  18.5k|    unsigned long line_number = 1;
  429|  18.5k|    const char *line_start = input;
  430|       |
  431|  18.5k|    Tokens r;
  432|       |
  433|  18.5k|    const char *c = input;
  434|       |
  435|  18.5k|    Fodder fodder;
  436|  18.5k|    bool fresh_line = true;  // Are we tokenizing from the beginning of a new line?
  437|       |
  438|   137M|    while (*c != '\0') {
  ------------------
  |  Branch (438:12): [True: 137M, False: 8.25k]
  ------------------
  439|       |        // Used to ensure we have actually advanced the pointer by the end of the iteration.
  440|   137M|        const char *original_c = c;
  441|       |
  442|   137M|        Token::Kind kind;
  443|   137M|        std::string data;
  444|   137M|        std::string string_block_indent;
  445|   137M|        std::string string_block_term_indent;
  446|       |
  447|   137M|        unsigned new_lines, indent;
  448|   137M|        lex_ws(c, new_lines, indent, line_start, line_number);
  449|       |
  450|       |        // If it's the end of the file, discard final whitespace.
  451|   137M|        if (*c == '\0')
  ------------------
  |  Branch (451:13): [True: 9.68k, False: 137M]
  ------------------
  452|  9.68k|            break;
  453|       |
  454|   137M|        if (new_lines > 0) {
  ------------------
  |  Branch (454:13): [True: 14.0M, False: 123M]
  ------------------
  455|       |            // Otherwise store whitespace in fodder.
  456|  14.0M|            unsigned blanks = new_lines - 1;
  457|  14.0M|            fodder.emplace_back(FodderElement::LINE_END, blanks, indent, EMPTY);
  458|  14.0M|            fresh_line = true;
  459|  14.0M|        }
  460|       |
  461|   137M|        Location begin(line_number, c - line_start + 1);
  462|       |
  463|   137M|        switch (*c) {
  464|       |            // The following operators should never be combined with subsequent symbols.
  465|   536k|            case '{':
  ------------------
  |  Branch (465:13): [True: 536k, False: 136M]
  ------------------
  466|   536k|                kind = Token::BRACE_L;
  467|   536k|                c++;
  468|   536k|                break;
  469|       |
  470|   531k|            case '}':
  ------------------
  |  Branch (470:13): [True: 531k, False: 136M]
  ------------------
  471|   531k|                kind = Token::BRACE_R;
  472|   531k|                c++;
  473|   531k|                break;
  474|       |
  475|  2.92M|            case '[':
  ------------------
  |  Branch (475:13): [True: 2.92M, False: 134M]
  ------------------
  476|  2.92M|                kind = Token::BRACKET_L;
  477|  2.92M|                c++;
  478|  2.92M|                break;
  479|       |
  480|  2.91M|            case ']':
  ------------------
  |  Branch (480:13): [True: 2.91M, False: 134M]
  ------------------
  481|  2.91M|                kind = Token::BRACKET_R;
  482|  2.91M|                c++;
  483|  2.91M|                break;
  484|       |
  485|  12.8M|            case ',':
  ------------------
  |  Branch (485:13): [True: 12.8M, False: 124M]
  ------------------
  486|  12.8M|                kind = Token::COMMA;
  487|  12.8M|                c++;
  488|  12.8M|                break;
  489|       |
  490|  6.58M|            case '.':
  ------------------
  |  Branch (490:13): [True: 6.58M, False: 130M]
  ------------------
  491|  6.58M|                kind = Token::DOT;
  492|  6.58M|                c++;
  493|  6.58M|                break;
  494|       |
  495|  9.96M|            case '(':
  ------------------
  |  Branch (495:13): [True: 9.96M, False: 127M]
  ------------------
  496|  9.96M|                kind = Token::PAREN_L;
  497|  9.96M|                c++;
  498|  9.96M|                break;
  499|       |
  500|  9.95M|            case ')':
  ------------------
  |  Branch (500:13): [True: 9.95M, False: 127M]
  ------------------
  501|  9.95M|                kind = Token::PAREN_R;
  502|  9.95M|                c++;
  503|  9.95M|                break;
  504|       |
  505|  2.60M|            case ';':
  ------------------
  |  Branch (505:13): [True: 2.60M, False: 134M]
  ------------------
  506|  2.60M|                kind = Token::SEMICOLON;
  507|  2.60M|                c++;
  508|  2.60M|                break;
  509|       |
  510|       |            // Numeric literals.
  511|  1.55M|            case '0':
  ------------------
  |  Branch (511:13): [True: 1.55M, False: 135M]
  ------------------
  512|  3.15M|            case '1':
  ------------------
  |  Branch (512:13): [True: 1.60M, False: 135M]
  ------------------
  513|  3.47M|            case '2':
  ------------------
  |  Branch (513:13): [True: 323k, False: 136M]
  ------------------
  514|  4.13M|            case '3':
  ------------------
  |  Branch (514:13): [True: 654k, False: 136M]
  ------------------
  515|  4.28M|            case '4':
  ------------------
  |  Branch (515:13): [True: 151k, False: 136M]
  ------------------
  516|  4.30M|            case '5':
  ------------------
  |  Branch (516:13): [True: 25.3k, False: 137M]
  ------------------
  517|  5.86M|            case '6':
  ------------------
  |  Branch (517:13): [True: 1.55M, False: 135M]
  ------------------
  518|  5.99M|            case '7':
  ------------------
  |  Branch (518:13): [True: 132k, False: 136M]
  ------------------
  519|  6.45M|            case '8':
  ------------------
  |  Branch (519:13): [True: 457k, False: 136M]
  ------------------
  520|  7.35M|            case '9':
  ------------------
  |  Branch (520:13): [True: 904k, False: 136M]
  ------------------
  521|  7.35M|                kind = Token::NUMBER;
  522|  7.35M|                data = lex_number(c, filename, begin);
  523|  7.35M|                break;
  524|       |
  525|       |            // UString literals.
  526|   100k|            case '"': {
  ------------------
  |  Branch (526:13): [True: 100k, False: 136M]
  ------------------
  527|   100k|                c++;
  528|  28.4M|                for (;; ++c) {
  529|  28.4M|                    if (*c == '\0') {
  ------------------
  |  Branch (529:25): [True: 29, False: 28.4M]
  ------------------
  530|     29|                        throw StaticError(filename, begin, "unterminated string");
  531|     29|                    }
  532|  28.4M|                    if (*c == '"') {
  ------------------
  |  Branch (532:25): [True: 100k, False: 28.3M]
  ------------------
  533|   100k|                        break;
  534|   100k|                    }
  535|  28.3M|                    if (*c == '\\' && *(c + 1) != '\0') {
  ------------------
  |  Branch (535:25): [True: 44.5k, False: 28.3M]
  |  Branch (535:39): [True: 44.5k, False: 2]
  ------------------
  536|  44.5k|                        data += *c;
  537|  44.5k|                        ++c;
  538|  44.5k|                    }
  539|  28.3M|                    if (*c == '\n') {
  ------------------
  |  Branch (539:25): [True: 6.45M, False: 21.9M]
  ------------------
  540|       |                        // Maintain line/column counters.
  541|  6.45M|                        line_number++;
  542|  6.45M|                        line_start = c + 1;
  543|  6.45M|                    }
  544|  28.3M|                    data += *c;
  545|  28.3M|                }
  546|   100k|                c++;  // Advance beyond the ".
  547|   100k|                kind = Token::STRING_DOUBLE;
  548|   100k|            } break;
  549|       |
  550|       |            // UString literals.
  551|  4.36M|            case '\'': {
  ------------------
  |  Branch (551:13): [True: 4.36M, False: 132M]
  ------------------
  552|  4.36M|                c++;
  553|  56.6M|                for (;; ++c) {
  554|  56.6M|                    if (*c == '\0') {
  ------------------
  |  Branch (554:25): [True: 31, False: 56.6M]
  ------------------
  555|     31|                        throw StaticError(filename, begin, "unterminated string");
  556|     31|                    }
  557|  56.6M|                    if (*c == '\'') {
  ------------------
  |  Branch (557:25): [True: 4.36M, False: 52.2M]
  ------------------
  558|  4.36M|                        break;
  559|  4.36M|                    }
  560|  52.2M|                    if (*c == '\\' && *(c + 1) != '\0') {
  ------------------
  |  Branch (560:25): [True: 471k, False: 51.7M]
  |  Branch (560:39): [True: 471k, False: 1]
  ------------------
  561|   471k|                        data += *c;
  562|   471k|                        ++c;
  563|   471k|                    }
  564|  52.2M|                    if (*c == '\n') {
  ------------------
  |  Branch (564:25): [True: 980k, False: 51.2M]
  ------------------
  565|       |                        // Maintain line/column counters.
  566|   980k|                        line_number++;
  567|   980k|                        line_start = c + 1;
  568|   980k|                    }
  569|  52.2M|                    data += *c;
  570|  52.2M|                }
  571|  4.36M|                c++;  // Advance beyond the '.
  572|  4.36M|                kind = Token::STRING_SINGLE;
  573|  4.36M|            } break;
  574|       |
  575|       |            // Verbatim string literals.
  576|       |            // ' and " quoting is interpreted here, unlike non-verbatim strings
  577|       |            // where it is done later by jsonnet_string_unescape.  This is OK
  578|       |            // in this case because no information is lost by resoving the
  579|       |            // repeated quote into a single quote, so we can go back to the
  580|       |            // original form in the formatter.
  581|  4.24k|            case '@': {
  ------------------
  |  Branch (581:13): [True: 4.24k, False: 137M]
  ------------------
  582|  4.24k|                c++;
  583|  4.24k|                if (*c != '"' && *c != '\'') {
  ------------------
  |  Branch (583:21): [True: 2.56k, False: 1.68k]
  |  Branch (583:34): [True: 13, False: 2.54k]
  ------------------
  584|     13|                    std::stringstream ss;
  585|     13|                    ss << "couldn't lex verbatim string, junk after '@': " << *c;
  586|     13|                    throw StaticError(filename, begin, ss.str());
  587|     13|                }
  588|  4.23k|                const char quot = *c;
  589|  4.23k|                c++;  // Advance beyond the opening quote.
  590|   104k|                for (;; ++c) {
  591|   104k|                    if (*c == '\0') {
  ------------------
  |  Branch (591:25): [True: 32, False: 104k]
  ------------------
  592|     32|                        throw StaticError(filename, begin, "unterminated verbatim string");
  593|     32|                    }
  594|   104k|                    if (*c == quot) {
  ------------------
  |  Branch (594:25): [True: 4.53k, False: 100k]
  ------------------
  595|  4.53k|                        if (*(c + 1) == quot) {
  ------------------
  |  Branch (595:29): [True: 331, False: 4.20k]
  ------------------
  596|    331|                            c++;
  597|  4.20k|                        } else {
  598|  4.20k|                            break;
  599|  4.20k|                        }
  600|  4.53k|                    }
  601|   100k|                    data += *c;
  602|   100k|                }
  603|  4.20k|                c++;  // Advance beyond the closing quote.
  604|  4.20k|                if (quot == '"') {
  ------------------
  |  Branch (604:21): [True: 1.67k, False: 2.53k]
  ------------------
  605|  1.67k|                    kind = Token::VERBATIM_STRING_DOUBLE;
  606|  2.53k|                } else {
  607|  2.53k|                    kind = Token::VERBATIM_STRING_SINGLE;
  608|  2.53k|                }
  609|  4.20k|            } break;
  610|       |
  611|       |            // Keywords
  612|  76.3M|            default:
  ------------------
  |  Branch (612:13): [True: 76.3M, False: 60.7M]
  ------------------
  613|  76.3M|                if (is_identifier_first(*c)) {
  ------------------
  |  Branch (613:21): [True: 55.8M, False: 20.5M]
  ------------------
  614|  55.8M|                    std::string id;
  615|   301M|                    for (; is_identifier(*c); ++c)
  ------------------
  |  Branch (615:28): [True: 246M, False: 55.8M]
  ------------------
  616|   246M|                        id += *c;
  617|  55.8M|                    kind = lex_get_keyword_kind(id);
  618|  55.8M|                    data = id;
  619|       |
  620|  55.8M|                } else if (is_symbol(*c) || *c == '#') {
  ------------------
  |  Branch (620:28): [True: 16.0M, False: 4.55M]
  |  Branch (620:45): [True: 4.55M, False: 166]
  ------------------
  621|       |                    // Single line C++ and Python style comments.
  622|  20.5M|                    if (*c == '#' || (*c == '/' && *(c + 1) == '/')) {
  ------------------
  |  Branch (622:25): [True: 4.55M, False: 16.0M]
  |  Branch (622:39): [True: 1.64M, False: 14.3M]
  |  Branch (622:52): [True: 836k, False: 806k]
  ------------------
  623|  5.38M|                        std::vector<std::string> comment(1);
  624|  5.38M|                        unsigned blanks;
  625|  5.38M|                        unsigned indent;
  626|  5.38M|                        lex_until_newline(c, comment[0], blanks, indent, line_start, line_number);
  627|  5.38M|                        auto kind = fresh_line ? FodderElement::PARAGRAPH : FodderElement::LINE_END;
  ------------------
  |  Branch (627:37): [True: 5.34M, False: 41.2k]
  ------------------
  628|  5.38M|                        fodder.emplace_back(kind, blanks, indent, comment);
  629|  5.38M|                        fresh_line = true;
  630|  5.38M|                        continue;  // We've not got a token, just fodder, so keep scanning.
  631|  5.38M|                    }
  632|       |
  633|       |                    // Multi-line C style comment.
  634|  15.1M|                    if (*c == '/' && *(c + 1) == '*') {
  ------------------
  |  Branch (634:25): [True: 806k, False: 14.3M]
  |  Branch (634:38): [True: 721k, False: 85.1k]
  ------------------
  635|   721k|                        unsigned margin = c - line_start;
  636|       |
  637|   721k|                        const char *initial_c = c;
  638|   721k|                        c += 2;  // Avoid matching /*/: skip the /* before starting the search for
  639|       |                                 // */.
  640|       |
  641|  52.2M|                        while (!(*c == '*' && *(c + 1) == '/')) {
  ------------------
  |  Branch (641:34): [True: 1.12M, False: 51.1M]
  |  Branch (641:47): [True: 721k, False: 406k]
  ------------------
  642|  51.5M|                            if (*c == '\0') {
  ------------------
  |  Branch (642:33): [True: 89, False: 51.5M]
  ------------------
  643|     89|                                auto msg = "multi-line comment has no terminating */.";
  644|     89|                                throw StaticError(filename, begin, msg);
  645|     89|                            }
  646|  51.5M|                            if (*c == '\n') {
  ------------------
  |  Branch (646:33): [True: 7.19M, False: 44.3M]
  ------------------
  647|       |                                // Just keep track of the line / column counters.
  648|  7.19M|                                line_number++;
  649|  7.19M|                                line_start = c + 1;
  650|  7.19M|                            }
  651|  51.5M|                            ++c;
  652|  51.5M|                        }
  653|   721k|                        c += 2;  // Move the pointer to the char after the closing '/'.
  654|       |
  655|   721k|                        std::string comment(initial_c,
  656|   721k|                                            c - initial_c);  // Includes the "/*" and "*/".
  657|       |
  658|       |                        // Lex whitespace after comment
  659|   721k|                        unsigned new_lines_after, indent_after;
  660|   721k|                        lex_ws(c, new_lines_after, indent_after, line_start, line_number);
  661|   721k|                        std::vector<std::string> lines;
  662|   721k|                        if (comment.find('\n') >= comment.length()) {
  ------------------
  |  Branch (662:29): [True: 473k, False: 247k]
  ------------------
  663|       |                            // Comment looks like /* foo */
  664|   473k|                            lines.push_back(comment);
  665|   473k|                            fodder.emplace_back(FodderElement::INTERSTITIAL, 0, 0, lines);
  666|   473k|                            if (new_lines_after > 0) {
  ------------------
  |  Branch (666:33): [True: 431k, False: 41.9k]
  ------------------
  667|   431k|                                fodder.emplace_back(FodderElement::LINE_END,
  668|   431k|                                                    new_lines_after - 1,
  669|   431k|                                                    indent_after,
  670|   431k|                                                    EMPTY);
  671|   431k|                                fresh_line = true;
  672|   431k|                            }
  673|   473k|                        } else {
  674|   247k|                            lines = line_split(comment, margin);
  675|   247k|                            assert(lines[0][0] == '/');
  676|       |                            // Little hack to support PARAGRAPHs with * down the LHS:
  677|       |                            // Add a space to lines that start with a '*'
  678|      0|                            bool all_star = true;
  679|  7.44M|                            for (auto &l : lines) {
  ------------------
  |  Branch (679:42): [True: 7.44M, False: 247k]
  ------------------
  680|  7.44M|                                if (l[0] != '*')
  ------------------
  |  Branch (680:37): [True: 7.34M, False: 95.6k]
  ------------------
  681|  7.34M|                                    all_star = false;
  682|  7.44M|                            }
  683|   247k|                            if (all_star) {
  ------------------
  |  Branch (683:33): [True: 0, False: 247k]
  ------------------
  684|      0|                                for (auto &l : lines) {
  ------------------
  |  Branch (684:46): [True: 0, False: 0]
  ------------------
  685|      0|                                    if (l[0] == '*')
  ------------------
  |  Branch (685:41): [True: 0, False: 0]
  ------------------
  686|      0|                                        l = " " + l;
  687|      0|                                }
  688|      0|                            }
  689|   247k|                            if (new_lines_after == 0) {
  ------------------
  |  Branch (689:33): [True: 19.4k, False: 228k]
  ------------------
  690|       |                                // Ensure a line end after the paragraph.
  691|  19.4k|                                new_lines_after = 1;
  692|  19.4k|                                indent_after = 0;
  693|  19.4k|                            }
  694|   247k|                            fodder_push_back(fodder,
  695|   247k|                                             FodderElement(FodderElement::PARAGRAPH,
  696|   247k|                                                           new_lines_after - 1,
  697|   247k|                                                           indent_after,
  698|   247k|                                                           lines));
  699|   247k|                            fresh_line = true;
  700|   247k|                        }
  701|      0|                        continue;  // We've not got a token, just fodder, so keep scanning.
  702|   721k|                    }
  703|       |
  704|       |                    // Text block
  705|  14.4M|                    if (*c == '|' && *(c + 1) == '|' && *(c + 2) == '|') {
  ------------------
  |  Branch (705:25): [True: 257k, False: 14.2M]
  |  Branch (705:38): [True: 200k, False: 57.2k]
  |  Branch (705:57): [True: 5.60k, False: 195k]
  ------------------
  706|  5.60k|                        c += 3;  // Skip the "|||".
  707|  6.78k|                        while (is_horz_ws(*c)) ++c;  // Chomp whitespace at end of line.
  ------------------
  |  Branch (707:32): [True: 1.17k, False: 5.60k]
  ------------------
  708|  5.60k|                        if (*c != '\n') {
  ------------------
  |  Branch (708:29): [True: 36, False: 5.57k]
  ------------------
  709|     36|                            auto msg = "text block syntax requires new line after |||.";
  710|     36|                            throw StaticError(filename, begin, msg);
  711|     36|                        }
  712|  5.57k|                        std::stringstream block;
  713|  5.57k|                        c++;  // Skip the "\n"
  714|  5.57k|                        line_number++;
  715|       |                        // Skip any blank lines at the beginning of the block.
  716|  6.22k|                        while (*c == '\n') {
  ------------------
  |  Branch (716:32): [True: 649, False: 5.57k]
  ------------------
  717|    649|                            line_number++;
  718|    649|                            ++c;
  719|    649|                            block << '\n';
  720|    649|                        }
  721|  5.57k|                        line_start = c;
  722|  5.57k|                        const char *first_line = c;
  723|  5.57k|                        int ws_chars = whitespace_check(first_line, c);
  724|  5.57k|                        string_block_indent = std::string(first_line, ws_chars);
  725|  5.57k|                        if (ws_chars == 0) {
  ------------------
  |  Branch (725:29): [True: 24, False: 5.54k]
  ------------------
  726|     24|                            auto msg = "text block's first line must start with whitespace.";
  727|     24|                            throw StaticError(filename, begin, msg);
  728|     24|                        }
  729|  6.82k|                        while (true) {
  ------------------
  |  Branch (729:32): [Folded - Ignored]
  ------------------
  730|  6.82k|                            assert(ws_chars > 0);
  731|       |                            // Read up to the \n
  732|  1.10M|                            for (c = &c[ws_chars]; *c != '\n'; ++c) {
  ------------------
  |  Branch (732:52): [True: 1.09M, False: 6.78k]
  ------------------
  733|  1.09M|                                if (*c == '\0')
  ------------------
  |  Branch (733:37): [True: 40, False: 1.09M]
  ------------------
  734|     40|                                    throw StaticError(filename, begin, "unexpected EOF");
  735|  1.09M|                                block << *c;
  736|  1.09M|                            }
  737|       |                            // Add the \n
  738|  6.78k|                            block << '\n';
  739|  6.78k|                            ++c;
  740|  6.78k|                            line_number++;
  741|  6.78k|                            line_start = c;
  742|       |                            // Skip any blank lines
  743|  7.23k|                            while (*c == '\n') {
  ------------------
  |  Branch (743:36): [True: 454, False: 6.78k]
  ------------------
  744|    454|                                line_number++;
  745|    454|                                ++c;
  746|    454|                                block << '\n';
  747|    454|                            }
  748|       |                            // Examine next line
  749|  6.78k|                            ws_chars = whitespace_check(first_line, c);
  750|  6.78k|                            if (ws_chars == 0) {
  ------------------
  |  Branch (750:33): [True: 5.50k, False: 1.27k]
  ------------------
  751|       |                                // End of text block
  752|       |                                // Skip over any whitespace
  753|  13.6k|                                while (*c == ' ' || *c == '\t') {
  ------------------
  |  Branch (753:40): [True: 7.27k, False: 6.38k]
  |  Branch (753:53): [True: 874, False: 5.50k]
  ------------------
  754|  8.14k|                                    string_block_term_indent += *c;
  755|  8.14k|                                    ++c;
  756|  8.14k|                                }
  757|       |                                // Expect |||
  758|  5.50k|                                if (!(*c == '|' && *(c + 1) == '|' && *(c + 2) == '|')) {
  ------------------
  |  Branch (758:39): [True: 5.43k, False: 75]
  |  Branch (758:52): [True: 5.42k, False: 8]
  |  Branch (758:71): [True: 5.41k, False: 11]
  ------------------
  759|     94|                                    auto msg = "text block not terminated with |||";
  760|     94|                                    throw StaticError(filename, begin, msg);
  761|     94|                                }
  762|  5.41k|                                c += 3;  // Leave after the last |
  763|  5.41k|                                data = block.str();
  764|  5.41k|                                kind = Token::STRING_BLOCK;
  765|  5.41k|                                break;  // Out of the while loop.
  766|  5.50k|                            }
  767|  6.78k|                        }
  768|       |
  769|  5.41k|                        break;  // Out of the switch.
  770|  5.54k|                    }
  771|       |
  772|  14.4M|                    const char *operator_begin = c;
  773|  42.0M|                    for (; is_symbol(*c); ++c) {
  ------------------
  |  Branch (773:28): [True: 27.6M, False: 14.4M]
  ------------------
  774|       |                        // Not allowed // in operators
  775|  27.6M|                        if (*c == '/' && *(c + 1) == '/')
  ------------------
  |  Branch (775:29): [True: 87.3k, False: 27.5M]
  |  Branch (775:42): [True: 410, False: 86.9k]
  ------------------
  776|    410|                            break;
  777|       |                        // Not allowed /* in operators
  778|  27.6M|                        if (*c == '/' && *(c + 1) == '*')
  ------------------
  |  Branch (778:29): [True: 86.9k, False: 27.5M]
  |  Branch (778:42): [True: 1.52k, False: 85.3k]
  ------------------
  779|  1.52k|                            break;
  780|       |                        // Not allowed ||| in operators
  781|  27.6M|                        if (*c == '|' && *(c + 1) == '|' && *(c + 2) == '|')
  ------------------
  |  Branch (781:29): [True: 453k, False: 27.1M]
  |  Branch (781:42): [True: 201k, False: 252k]
  |  Branch (781:61): [True: 6.31k, False: 195k]
  ------------------
  782|  6.31k|                            break;
  783|  27.6M|                    }
  784|       |                    // Not allowed to end with a + - ~ ! unless a single char.
  785|       |                    // So, wind it back if we need to (but not too far).
  786|  23.1M|                    while (c > operator_begin + 1 && !allowed_at_end_of_operator(*(c - 1))) {
  ------------------
  |  Branch (786:28): [True: 12.6M, False: 10.5M]
  |  Branch (786:54): [True: 8.73M, False: 3.94M]
  ------------------
  787|  8.73M|                        c--;
  788|  8.73M|                    }
  789|  14.4M|                    data += std::string(operator_begin, c);
  790|  14.4M|                    if (data == "$") {
  ------------------
  |  Branch (790:25): [True: 42.3k, False: 14.4M]
  ------------------
  791|  42.3k|                        kind = Token::DOLLAR;
  792|  42.3k|                        data = "";
  793|  14.4M|                    } else {
  794|  14.4M|                        kind = Token::OPERATOR;
  795|  14.4M|                    }
  796|  14.4M|                } else {
  797|    166|                    std::stringstream ss;
  798|    166|                    ss << "Could not lex the character ";
  799|    166|                    auto uc = (unsigned char)(*c);
  800|    166|                    if (*c < 32)
  ------------------
  |  Branch (800:25): [True: 157, False: 9]
  ------------------
  801|    157|                        ss << "code " << unsigned(uc);
  802|      9|                    else
  803|      9|                        ss << "'" << *c << "'";
  804|    166|                    throw StaticError(filename, begin, ss.str());
  805|    166|                }
  806|   137M|        }
  807|       |
  808|       |        // Ensure that a bug in the above code does not cause an infinite memory consuming loop due
  809|       |        // to pushing empty tokens.
  810|   130M|        if (c == original_c) {
  ------------------
  |  Branch (810:13): [True: 0, False: 130M]
  ------------------
  811|      0|            throw StaticError(filename, begin, "internal lexing error:  pointer did not advance");
  812|      0|        }
  813|       |
  814|   130M|        Location end(line_number, (c + 1) - line_start);
  815|   130M|        r.emplace_back(kind,
  816|   130M|                       fodder,
  817|   130M|                       data,
  818|   130M|                       string_block_indent,
  819|   130M|                       string_block_term_indent,
  820|   130M|                       LocationRange(filename, begin, end));
  821|   130M|        fodder.clear();
  822|   130M|        fresh_line = false;
  823|   130M|    }
  824|       |
  825|  17.9k|    Location begin(line_number, c - line_start + 1);
  826|  17.9k|    Location end(line_number, (c + 1) - line_start + 1);
  827|  17.9k|    r.emplace_back(Token::END_OF_FILE, fodder, "", "", "", LocationRange(filename, begin, end));
  828|  17.9k|    return r;
  829|  18.5k|}
lexer.cpp:_ZN7jsonnet8internalL6lex_wsERPKcRjS4_S3_Rm:
   81|   143M|{
   82|   143M|    indent = 0;
   83|   143M|    new_lines = 0;
   84|   328M|    for (; *c != '\0' && is_ws(*c); c++) {
  ------------------
  |  Branch (84:12): [True: 328M, False: 10.4k]
  |  Branch (84:26): [True: 185M, False: 143M]
  ------------------
   85|   185M|        switch (*c) {
  ------------------
  |  Branch (85:17): [True: 0, False: 185M]
  ------------------
   86|  1.35M|            case '\r':
  ------------------
  |  Branch (86:13): [True: 1.35M, False: 184M]
  ------------------
   87|       |                // Ignore.
   88|  1.35M|                break;
   89|       |
   90|  27.7M|            case '\n':
  ------------------
  |  Branch (90:13): [True: 27.7M, False: 157M]
  ------------------
   91|  27.7M|                indent = 0;
   92|  27.7M|                new_lines++;
   93|  27.7M|                line_number++;
   94|  27.7M|                line_start = c + 1;
   95|  27.7M|                break;
   96|       |
   97|   156M|            case ' ': indent += 1; break;
  ------------------
  |  Branch (97:13): [True: 156M, False: 29.1M]
  ------------------
   98|       |
   99|       |            // This only works for \t at the beginning of lines, but we strip it everywhere else
  100|       |            // anyway.  The only case where this will cause a problem is spaces followed by \t
  101|       |            // at the beginning of a line.  However that is rare, ill-advised, and if re-indentation
  102|       |            // is enabled it will be fixed later.
  103|  23.7k|            case '\t': indent += 8; break;
  ------------------
  |  Branch (103:13): [True: 23.7k, False: 185M]
  ------------------
  104|   185M|        }
  105|   185M|    }
  106|   143M|}
lexer.cpp:_ZN7jsonnet8internalL5is_wsEc:
   39|   328M|{
   40|   328M|    return c == '\n' || is_horz_ws(c);
  ------------------
  |  Branch (40:12): [True: 27.7M, False: 301M]
  |  Branch (40:25): [True: 157M, False: 143M]
  ------------------
   41|   328M|}
lexer.cpp:_ZN7jsonnet8internalL19is_identifier_firstEc:
  143|   378M|{
  144|   378M|    return is_upper(c) || is_lower(c) || c == '_';
  ------------------
  |  Branch (144:12): [True: 5.90M, False: 372M]
  |  Branch (144:27): [True: 279M, False: 92.8M]
  |  Branch (144:42): [True: 4.23M, False: 88.6M]
  ------------------
  145|   378M|}
lexer.cpp:_ZN7jsonnet8internalL8is_upperEc:
  128|   378M|{
  129|   378M|    return c >= 'A' && c <= 'Z';
  ------------------
  |  Branch (129:12): [True: 293M, False: 85.2M]
  |  Branch (129:24): [True: 5.90M, False: 287M]
  ------------------
  130|   378M|}
lexer.cpp:_ZN7jsonnet8internalL8is_lowerEc:
  133|   372M|{
  134|   372M|    return c >= 'a' && c <= 'z';
  ------------------
  |  Branch (134:12): [True: 279M, False: 92.5M]
  |  Branch (134:24): [True: 279M, False: 266k]
  ------------------
  135|   372M|}
lexer.cpp:_ZN7jsonnet8internalL13is_identifierEc:
  148|   301M|{
  149|   301M|    return is_identifier_first(c) || is_number(c);
  ------------------
  |  Branch (149:12): [True: 233M, False: 68.0M]
  |  Branch (149:38): [True: 12.2M, False: 55.8M]
  ------------------
  150|   301M|}
lexer.cpp:_ZN7jsonnet8internalL9is_numberEc:
  138|  68.0M|{
  139|  68.0M|    return c >= '0' && c <= '9';
  ------------------
  |  Branch (139:12): [True: 17.1M, False: 50.9M]
  |  Branch (139:24): [True: 12.2M, False: 4.87M]
  ------------------
  140|  68.0M|}
lexer.cpp:_ZN7jsonnet8internalL9is_symbolEc:
  153|  62.6M|{
  154|  62.6M|    switch (c) {
  ------------------
  |  Branch (154:13): [True: 19.0M, False: 43.6M]
  ------------------
  155|  1.23M|        case '!':
  ------------------
  |  Branch (155:9): [True: 1.23M, False: 61.4M]
  ------------------
  156|  1.46M|        case '$':
  ------------------
  |  Branch (156:9): [True: 230k, False: 62.4M]
  ------------------
  157|  8.02M|        case ':':
  ------------------
  |  Branch (157:9): [True: 6.56M, False: 56.0M]
  ------------------
  158|  8.06M|        case '~':
  ------------------
  |  Branch (158:9): [True: 42.1k, False: 62.5M]
  ------------------
  159|  24.3M|        case '+':
  ------------------
  |  Branch (159:9): [True: 16.2M, False: 46.3M]
  ------------------
  160|  25.6M|        case '-':
  ------------------
  |  Branch (160:9): [True: 1.37M, False: 61.2M]
  ------------------
  161|  27.0M|        case '&':
  ------------------
  |  Branch (161:9): [True: 1.38M, False: 61.2M]
  ------------------
  162|  27.7M|        case '|':
  ------------------
  |  Branch (162:9): [True: 711k, False: 61.9M]
  ------------------
  163|  27.8M|        case '^':
  ------------------
  |  Branch (163:9): [True: 85.2k, False: 62.5M]
  ------------------
  164|  38.2M|        case '=':
  ------------------
  |  Branch (164:9): [True: 10.3M, False: 52.2M]
  ------------------
  165|  39.3M|        case '<':
  ------------------
  |  Branch (165:9): [True: 1.13M, False: 61.5M]
  ------------------
  166|  40.9M|        case '>':
  ------------------
  |  Branch (166:9): [True: 1.62M, False: 61.0M]
  ------------------
  167|  41.2M|        case '*':
  ------------------
  |  Branch (167:9): [True: 288k, False: 62.3M]
  ------------------
  168|  43.0M|        case '/':
  ------------------
  |  Branch (168:9): [True: 1.73M, False: 60.9M]
  ------------------
  169|  43.6M|        case '%': return true;
  ------------------
  |  Branch (169:9): [True: 629k, False: 62.0M]
  ------------------
  170|  62.6M|    }
  171|  19.0M|    return false;
  172|  62.6M|}
lexer.cpp:_ZN7jsonnet8internalL17lex_until_newlineERPKcRNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEERjSC_S3_Rm:
  113|  5.38M|{
  114|  5.38M|    const char *original_c = c;
  115|  5.38M|    const char *last_non_space = c;
  116|  59.4M|    for (; *c != '\0' && *c != '\n'; c++) {
  ------------------
  |  Branch (116:12): [True: 59.4M, False: 317]
  |  Branch (116:26): [True: 54.1M, False: 5.38M]
  ------------------
  117|  54.1M|        if (!is_horz_ws(*c))
  ------------------
  |  Branch (117:13): [True: 47.4M, False: 6.69M]
  ------------------
  118|  47.4M|            last_non_space = c;
  119|  54.1M|    }
  120|  5.38M|    text = std::string(original_c, last_non_space - original_c + 1);
  121|       |    // Consume subsequent whitespace including the '\n'.
  122|  5.38M|    unsigned new_lines;
  123|  5.38M|    lex_ws(c, new_lines, indent, line_start, line_number);
  124|  5.38M|    blanks = new_lines == 0 ? 0 : new_lines - 1;
  ------------------
  |  Branch (124:14): [True: 317, False: 5.38M]
  ------------------
  125|  5.38M|}
lexer.cpp:_ZN7jsonnet8internalL10line_splitERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEj:
   60|   247k|{
   61|   247k|    std::vector<std::string> ret;
   62|   247k|    std::stringstream ss;
   63|  48.9M|    for (size_t i = 0; i < s.length(); ++i) {
  ------------------
  |  Branch (63:24): [True: 48.7M, False: 247k]
  ------------------
   64|  48.7M|        if (s[i] == '\n') {
  ------------------
  |  Branch (64:13): [True: 7.19M, False: 41.5M]
  ------------------
   65|  7.19M|            ret.emplace_back(strip_ws(ss.str(), margin));
   66|  7.19M|            ss.str("");
   67|  41.5M|        } else {
   68|  41.5M|            ss << s[i];
   69|  41.5M|        }
   70|  48.7M|    }
   71|   247k|    ret.emplace_back(strip_ws(ss.str(), margin));
   72|   247k|    return ret;
   73|   247k|}
lexer.cpp:_ZN7jsonnet8internalL8strip_wsERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEj:
   45|  7.44M|{
   46|  7.44M|    if (s.size() == 0)
  ------------------
  |  Branch (46:9): [True: 6.20M, False: 1.24M]
  ------------------
   47|  6.20M|        return s;  // Avoid underflow below.
   48|  1.24M|    size_t i = 0;
   49|  3.51M|    while (i < s.length() && is_horz_ws(s[i]) && i < margin)
  ------------------
  |  Branch (49:12): [True: 3.51M, False: 2.81k]
  |  Branch (49:30): [True: 2.73M, False: 778k]
  |  Branch (49:50): [True: 2.27M, False: 459k]
  ------------------
   50|  2.27M|        i++;
   51|  1.24M|    size_t j = s.size();
   52|  2.76M|    while (j > i && is_horz_ws(s[j - 1])) {
  ------------------
  |  Branch (52:12): [True: 2.66M, False: 97.4k]
  |  Branch (52:21): [True: 1.52M, False: 1.14M]
  ------------------
   53|  1.52M|        j--;
   54|  1.52M|    }
   55|  1.24M|    return std::string(&s[i], &s[j]);
   56|  7.44M|}
lexer.cpp:_ZN7jsonnet8internalL10is_horz_wsEc:
   33|   361M|{
   34|   361M|    return c == ' ' || c == '\t' || c == '\r';
  ------------------
  |  Branch (34:12): [True: 167M, False: 194M]
  |  Branch (34:24): [True: 78.0k, False: 194M]
  |  Branch (34:37): [True: 1.45M, False: 192M]
  ------------------
   35|   361M|}
lexer.cpp:_ZN7jsonnet8internalL16whitespace_checkEPKcS2_:
  404|  12.3k|{
  405|  12.3k|    int i = 0;
  406|  74.9k|    while (a[i] == ' ' || a[i] == '\t') {
  ------------------
  |  Branch (406:12): [True: 24.5k, False: 50.4k]
  |  Branch (406:27): [True: 43.5k, False: 6.84k]
  ------------------
  407|  68.0k|        if (b[i] != a[i])
  ------------------
  |  Branch (407:13): [True: 5.50k, False: 62.5k]
  ------------------
  408|  5.50k|            return 0;
  409|  62.5k|        i++;
  410|  62.5k|    }
  411|  6.84k|    return i;
  412|  12.3k|}

_ZN7jsonnet8internal13FodderElementC2ENS1_4KindEjjRKNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEE:
   93|  20.6M|    {
   94|  20.6M|        assert(kind != LINE_END || comment.size() <= 1);
   95|      0|        assert(kind != INTERSTITIAL || (blanks == 0 && indent == 0 && comment.size() == 1));
   96|      0|        assert(kind != PARAGRAPH || comment.size() >= 1);
   97|  20.6M|    }
_ZNK7jsonnet8internal5Token6data32Ev:
  299|  45.2M|    {
  300|  45.2M|        return decode_utf8(data);
  301|  45.2M|    }
_ZN7jsonnet8internal5TokenC2ENS1_4KindERKNSt3__16vectorINS0_13FodderElementENS3_9allocatorIS5_EEEERKNS3_12basic_stringIcNS3_11char_traitsIcEENS6_IcEEEESH_SH_RKNS0_13LocationRangeE:
  314|   131M|    {
  315|   131M|    }
_ZN7jsonnet8internal5Token8toStringENS1_4KindE:
  320|  1.45k|    {
  321|  1.45k|        switch (v) {
  322|     19|            case BRACE_L: return "\"{\"";
  ------------------
  |  Branch (322:13): [True: 19, False: 1.43k]
  ------------------
  323|     45|            case BRACE_R: return "\"}\"";
  ------------------
  |  Branch (323:13): [True: 45, False: 1.40k]
  ------------------
  324|      6|            case BRACKET_L: return "\"[\"";
  ------------------
  |  Branch (324:13): [True: 6, False: 1.44k]
  ------------------
  325|    126|            case BRACKET_R: return "\"]\"";
  ------------------
  |  Branch (325:13): [True: 126, False: 1.32k]
  ------------------
  326|     60|            case COMMA: return "\",\"";
  ------------------
  |  Branch (326:13): [True: 60, False: 1.39k]
  ------------------
  327|     20|            case DOLLAR: return "\"$\"";
  ------------------
  |  Branch (327:13): [True: 20, False: 1.43k]
  ------------------
  328|     22|            case DOT: return "\".\"";
  ------------------
  |  Branch (328:13): [True: 22, False: 1.42k]
  ------------------
  329|       |
  330|      0|            case PAREN_L: return "\"(\"";
  ------------------
  |  Branch (330:13): [True: 0, False: 1.45k]
  ------------------
  331|     51|            case PAREN_R: return "\")\"";
  ------------------
  |  Branch (331:13): [True: 51, False: 1.40k]
  ------------------
  332|     30|            case SEMICOLON: return "\";\"";
  ------------------
  |  Branch (332:13): [True: 30, False: 1.42k]
  ------------------
  333|       |
  334|    186|            case IDENTIFIER: return "IDENTIFIER";
  ------------------
  |  Branch (334:13): [True: 186, False: 1.26k]
  ------------------
  335|     74|            case NUMBER: return "NUMBER";
  ------------------
  |  Branch (335:13): [True: 74, False: 1.37k]
  ------------------
  336|    202|            case OPERATOR: return "OPERATOR";
  ------------------
  |  Branch (336:13): [True: 202, False: 1.24k]
  ------------------
  337|     11|            case STRING_SINGLE: return "STRING_SINGLE";
  ------------------
  |  Branch (337:13): [True: 11, False: 1.44k]
  ------------------
  338|     20|            case STRING_DOUBLE: return "STRING_DOUBLE";
  ------------------
  |  Branch (338:13): [True: 20, False: 1.43k]
  ------------------
  339|      3|            case VERBATIM_STRING_SINGLE: return "VERBATIM_STRING_SINGLE";
  ------------------
  |  Branch (339:13): [True: 3, False: 1.44k]
  ------------------
  340|      3|            case VERBATIM_STRING_DOUBLE: return "VERBATIM_STRING_DOUBLE";
  ------------------
  |  Branch (340:13): [True: 3, False: 1.44k]
  ------------------
  341|     12|            case STRING_BLOCK: return "STRING_BLOCK";
  ------------------
  |  Branch (341:13): [True: 12, False: 1.43k]
  ------------------
  342|       |
  343|      0|            case ASSERT: return "assert";
  ------------------
  |  Branch (343:13): [True: 0, False: 1.45k]
  ------------------
  344|      2|            case ELSE: return "else";
  ------------------
  |  Branch (344:13): [True: 2, False: 1.44k]
  ------------------
  345|      0|            case ERROR: return "error";
  ------------------
  |  Branch (345:13): [True: 0, False: 1.45k]
  ------------------
  346|      0|            case FALSE: return "false";
  ------------------
  |  Branch (346:13): [True: 0, False: 1.45k]
  ------------------
  347|      3|            case FOR: return "for";
  ------------------
  |  Branch (347:13): [True: 3, False: 1.44k]
  ------------------
  348|      0|            case FUNCTION: return "function";
  ------------------
  |  Branch (348:13): [True: 0, False: 1.45k]
  ------------------
  349|      6|            case IF: return "if";
  ------------------
  |  Branch (349:13): [True: 6, False: 1.44k]
  ------------------
  350|      0|            case IMPORT: return "import";
  ------------------
  |  Branch (350:13): [True: 0, False: 1.45k]
  ------------------
  351|      1|            case IMPORTSTR: return "importstr";
  ------------------
  |  Branch (351:13): [True: 1, False: 1.45k]
  ------------------
  352|      1|            case IMPORTBIN: return "importbin";
  ------------------
  |  Branch (352:13): [True: 1, False: 1.45k]
  ------------------
  353|     29|            case IN: return "in";
  ------------------
  |  Branch (353:13): [True: 29, False: 1.42k]
  ------------------
  354|      1|            case LOCAL: return "local";
  ------------------
  |  Branch (354:13): [True: 1, False: 1.45k]
  ------------------
  355|      1|            case NULL_LIT: return "null";
  ------------------
  |  Branch (355:13): [True: 1, False: 1.45k]
  ------------------
  356|      1|            case SELF: return "self";
  ------------------
  |  Branch (356:13): [True: 1, False: 1.45k]
  ------------------
  357|      0|            case SUPER: return "super";
  ------------------
  |  Branch (357:13): [True: 0, False: 1.45k]
  ------------------
  358|      2|            case TAILSTRICT: return "tailstrict";
  ------------------
  |  Branch (358:13): [True: 2, False: 1.44k]
  ------------------
  359|      3|            case THEN: return "then";
  ------------------
  |  Branch (359:13): [True: 3, False: 1.44k]
  ------------------
  360|      2|            case TRUE: return "true";
  ------------------
  |  Branch (360:13): [True: 2, False: 1.44k]
  ------------------
  361|       |
  362|    509|            case END_OF_FILE: return "end of file";
  ------------------
  |  Branch (362:13): [True: 509, False: 942]
  ------------------
  363|      0|            default:
  ------------------
  |  Branch (363:13): [True: 0, False: 1.45k]
  ------------------
  364|      0|                std::cerr << "INTERNAL ERROR: Unknown token kind: " << v << std::endl;
  365|      0|                std::abort();
  366|  1.45k|        }
  367|  1.45k|    }
parser.cpp:_ZN7jsonnet8internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEENS0_5Token4KindE:
  387|    819|{
  388|    819|    o << Token::toString(v);
  389|    819|    return o;
  390|    819|}
parser.cpp:_ZN7jsonnet8internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_5TokenE:
  393|    676|{
  394|    676|    if (v.data == "") {
  ------------------
  |  Branch (394:9): [True: 456, False: 220]
  ------------------
  395|    456|        o << Token::toString(v.kind);
  396|    456|    } else if (v.kind == Token::OPERATOR) {
  ------------------
  |  Branch (396:16): [True: 44, False: 176]
  ------------------
  397|     44|        o << "\"" << v.data << "\"";
  398|    176|    } else {
  399|    176|        o << "(" << Token::toString(v.kind) << ", \"" << v.data << "\")";
  400|    176|    }
  401|    676|    return o;
  402|    676|}
lexer.cpp:_ZN7jsonnet8internalL16fodder_push_backERNSt3__16vectorINS0_13FodderElementENS1_9allocatorIS3_EEEERKS3_:
  143|   247k|{
  144|   247k|    if (fodder_has_clean_endline(a) && elem.kind == FodderElement::LINE_END) {
  ------------------
  |  Branch (144:9): [True: 228k, False: 18.9k]
  |  Branch (144:40): [True: 0, False: 228k]
  ------------------
  145|      0|        if (elem.comment.size() > 0) {
  ------------------
  |  Branch (145:13): [True: 0, False: 0]
  ------------------
  146|       |            // The line end had a comment, so create a single line paragraph for it.
  147|      0|            a.emplace_back(FodderElement::PARAGRAPH, elem.blanks, elem.indent, elem.comment);
  148|      0|        } else {
  149|       |            // Merge it into the previous line end.
  150|      0|            a.back().indent = elem.indent;
  151|      0|            a.back().blanks += elem.blanks;
  152|      0|        }
  153|   247k|    } else {
  154|   247k|        if (!fodder_has_clean_endline(a) && elem.kind == FodderElement::PARAGRAPH) {
  ------------------
  |  Branch (154:13): [True: 18.9k, False: 228k]
  |  Branch (154:45): [True: 18.9k, False: 0]
  ------------------
  155|  18.9k|            a.emplace_back(FodderElement::LINE_END, 0, elem.indent, std::vector<std::string>());
  156|  18.9k|        }
  157|   247k|        a.push_back(elem);
  158|   247k|    }
  159|   247k|}
lexer.cpp:_ZN7jsonnet8internalL24fodder_has_clean_endlineERKNSt3__16vectorINS0_13FodderElementENS1_9allocatorIS3_EEEE:
  134|   495k|{
  135|   495k|    return !fodder.empty() && fodder.back().kind != FodderElement::INTERSTITIAL;
  ------------------
  |  Branch (135:12): [True: 473k, False: 21.8k]
  |  Branch (135:31): [True: 457k, False: 16.1k]
  ------------------
  136|   495k|}

jsonnet_version:
  302|  18.5k|{
  303|  18.5k|    return LIB_JSONNET_VERSION;
  ------------------
  |  |   34|  18.5k|#define LIB_JSONNET_VERSION "v0.20.0"
  ------------------
  304|  18.5k|}
jsonnet_make:
  307|  9.27k|{
  308|  9.27k|    TRY
  ------------------
  |  |  287|  9.27k|#define TRY try {
  ------------------
  309|  9.27k|        return new JsonnetVm();
  310|  9.27k|    CATCH("jsonnet_make")
  ------------------
  |  |  289|  9.27k|    }                                                                                         \
  |  |  290|  9.27k|    catch (const std::bad_alloc &)                                                            \
  |  |  291|  9.27k|    {                                                                                         \
  |  |  292|      0|        memory_panic();                                                                       \
  |  |  293|      0|    }                                                                                         \
  |  |  294|  9.27k|    catch (const std::exception &e)                                                           \
  |  |  295|  9.27k|    {                                                                                         \
  |  |  296|      0|        std::cerr << "Something went wrong during " func ", please report this: " << e.what() \
  |  |  297|      0|                  << std::endl;                                                               \
  |  |  298|      0|        abort();                                                                              \
  |  |  299|      0|    }
  ------------------
  311|      0|    return nullptr;
  312|  9.27k|}
jsonnet_destroy:
  315|  9.27k|{
  316|  9.27k|    TRY
  ------------------
  |  |  287|  9.27k|#define TRY try {
  ------------------
  317|  9.27k|        delete vm;
  318|  9.27k|    CATCH("jsonnet_destroy")
  ------------------
  |  |  289|  9.27k|    }                                                                                         \
  |  |  290|  9.27k|    catch (const std::bad_alloc &)                                                            \
  |  |  291|  9.27k|    {                                                                                         \
  |  |  292|      0|        memory_panic();                                                                       \
  |  |  293|      0|    }                                                                                         \
  |  |  294|  9.27k|    catch (const std::exception &e)                                                           \
  |  |  295|  9.27k|    {                                                                                         \
  |  |  296|      0|        std::cerr << "Something went wrong during " func ", please report this: " << e.what() \
  |  |  297|      0|                  << std::endl;                                                               \
  |  |  298|      0|        abort();                                                                              \
  |  |  299|      0|    }
  ------------------
  319|  9.27k|}
jsonnet_import_callback:
  342|  9.27k|{
  343|  9.27k|    vm->importCallback = cb;
  344|  9.27k|    vm->importCallbackContext = ctx;
  345|  9.27k|}
jsonnet_evaluate_snippet_stream:
  700|  9.27k|{
  701|  9.27k|    TRY
  ------------------
  |  |  287|  9.27k|#define TRY try {
  ------------------
  702|  9.27k|        return jsonnet_evaluate_snippet_aux(vm, filename, snippet, error, STREAM);
  703|  9.27k|    CATCH("jsonnet_evaluate_snippet_stream")
  ------------------
  |  |  289|  9.27k|    }                                                                                         \
  |  |  290|  9.27k|    catch (const std::bad_alloc &)                                                            \
  |  |  291|  9.27k|    {                                                                                         \
  |  |  292|      0|        memory_panic();                                                                       \
  |  |  293|      0|    }                                                                                         \
  |  |  294|  9.27k|    catch (const std::exception &e)                                                           \
  |  |  295|  9.27k|    {                                                                                         \
  |  |  296|      0|        std::cerr << "Something went wrong during " func ", please report this: " << e.what() \
  |  |  297|      0|                  << std::endl;                                                               \
  |  |  298|      0|        abort();                                                                              \
  |  |  299|      0|    }
  ------------------
  704|      0|    return nullptr;  // Never happens.
  705|  9.27k|}
jsonnet_realloc:
  708|  17.8k|{
  709|  17.8k|    (void)vm;
  710|  17.8k|    if (str == nullptr) {
  ------------------
  |  Branch (710:9): [True: 8.55k, False: 9.27k]
  ------------------
  711|  8.55k|        if (sz == 0)
  ------------------
  |  Branch (711:13): [True: 0, False: 8.55k]
  ------------------
  712|      0|            return nullptr;
  713|  8.55k|        auto *r = static_cast<char *>(::malloc(sz));
  714|  8.55k|        if (r == nullptr)
  ------------------
  |  Branch (714:13): [True: 0, False: 8.55k]
  ------------------
  715|      0|            memory_panic();
  716|  8.55k|        return r;
  717|  9.27k|    } else {
  718|  9.27k|        if (sz == 0) {
  ------------------
  |  Branch (718:13): [True: 9.27k, False: 0]
  ------------------
  719|  9.27k|            ::free(str);
  720|  9.27k|            return nullptr;
  721|  9.27k|        } else {
  722|      0|            auto *r = static_cast<char *>(::realloc(str, sz));
  723|      0|            if (r == nullptr)
  ------------------
  |  Branch (723:17): [True: 0, False: 0]
  ------------------
  724|      0|                memory_panic();
  725|      0|            return r;
  726|      0|        }
  727|  9.27k|    }
  728|  17.8k|}
_ZN9JsonnetVmC2Ev:
  205|  9.27k|    {
  206|  9.27k|        jpaths.emplace_back("/usr/share/jsonnet-" + std::string(jsonnet_version()) + "/");
  207|  9.27k|        jpaths.emplace_back("/usr/local/share/jsonnet-" + std::string(jsonnet_version()) + "/");
  208|  9.27k|    }
libjsonnet.cpp:_ZL11from_stringP9JsonnetVmRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   60|  8.55k|{
   61|  8.55k|    char *r = jsonnet_realloc(vm, nullptr, v.length() + 1);
   62|  8.55k|    std::memcpy(r, v.c_str(), v.length() + 1);
   63|  8.55k|    return r;
   64|  8.55k|}
libjsonnet.cpp:_ZL28jsonnet_evaluate_snippet_auxP9JsonnetVmPKcS2_PiN12_GLOBAL__N_18EvalKindE:
  502|  9.27k|{
  503|  9.27k|    try {
  504|  9.27k|        Allocator alloc;
  505|  9.27k|        AST *expr;
  506|  9.27k|        Tokens tokens = jsonnet_lex(filename, snippet);
  507|       |
  508|  9.27k|        expr = jsonnet_parse(&alloc, tokens);
  509|       |
  510|  9.27k|        jsonnet_desugar(&alloc, expr, &vm->tla);
  511|       |
  512|  9.27k|        unsigned max_stack = vm->maxStack;
  513|       |
  514|       |        // For the stdlib desugaring.
  515|  9.27k|        max_stack++;
  516|       |
  517|       |        // For the TLA desugaring.
  518|  9.27k|        max_stack++;
  519|       |
  520|  9.27k|        jsonnet_static_analysis(expr);
  521|  9.27k|        switch (kind) {
  522|      0|            case REGULAR: {
  ------------------
  |  Branch (522:13): [True: 0, False: 9.27k]
  ------------------
  523|      0|                std::string json_str = jsonnet_vm_execute(&alloc,
  524|      0|                                                          expr,
  525|      0|                                                          vm->ext,
  526|      0|                                                          max_stack,
  527|      0|                                                          vm->gcMinObjects,
  528|      0|                                                          vm->gcGrowthTrigger,
  529|      0|                                                          vm->nativeCallbacks,
  530|      0|                                                          vm->importCallback,
  531|      0|                                                          vm->importCallbackContext,
  532|      0|                                                          vm->stringOutput);
  533|      0|                json_str += "\n";
  534|      0|                *error = false;
  535|      0|                return from_string(vm, json_str);
  536|      0|            } break;
  537|       |
  538|      0|            case MULTI: {
  ------------------
  |  Branch (538:13): [True: 0, False: 9.27k]
  ------------------
  539|      0|                std::map<std::string, std::string> files =
  540|      0|                    jsonnet_vm_execute_multi(&alloc,
  541|      0|                                             expr,
  542|      0|                                             vm->ext,
  543|      0|                                             max_stack,
  544|      0|                                             vm->gcMinObjects,
  545|      0|                                             vm->gcGrowthTrigger,
  546|      0|                                             vm->nativeCallbacks,
  547|      0|                                             vm->importCallback,
  548|      0|                                             vm->importCallbackContext,
  549|      0|                                             vm->stringOutput);
  550|      0|                size_t sz = 1;  // final sentinel
  551|      0|                for (const auto &pair : files) {
  ------------------
  |  Branch (551:39): [True: 0, False: 0]
  ------------------
  552|      0|                    sz += pair.first.length() + 1;   // include sentinel
  553|      0|                    sz += pair.second.length() + 2;  // Add a '\n' as well as sentinel
  554|      0|                }
  555|      0|                char *buf = (char *)::malloc(sz);
  556|      0|                if (buf == nullptr)
  ------------------
  |  Branch (556:21): [True: 0, False: 0]
  ------------------
  557|      0|                    memory_panic();
  558|      0|                std::ptrdiff_t i = 0;
  559|      0|                for (const auto &pair : files) {
  ------------------
  |  Branch (559:39): [True: 0, False: 0]
  ------------------
  560|      0|                    memcpy(&buf[i], pair.first.c_str(), pair.first.length() + 1);
  561|      0|                    i += pair.first.length() + 1;
  562|      0|                    memcpy(&buf[i], pair.second.c_str(), pair.second.length());
  563|      0|                    i += pair.second.length();
  564|      0|                    buf[i] = '\n';
  565|      0|                    i++;
  566|      0|                    buf[i] = '\0';
  567|      0|                    i++;
  568|      0|                }
  569|      0|                buf[i] = '\0';  // final sentinel
  570|      0|                *error = false;
  571|      0|                return buf;
  572|      0|            } break;
  573|       |
  574|  4.16k|            case STREAM: {
  ------------------
  |  Branch (574:13): [True: 4.16k, False: 5.10k]
  ------------------
  575|  4.16k|                std::vector<std::string> documents =
  576|  4.16k|                    jsonnet_vm_execute_stream(&alloc,
  577|  4.16k|                                              expr,
  578|  4.16k|                                              vm->ext,
  579|  4.16k|                                              max_stack,
  580|  4.16k|                                              vm->gcMinObjects,
  581|  4.16k|                                              vm->gcGrowthTrigger,
  582|  4.16k|                                              vm->nativeCallbacks,
  583|  4.16k|                                              vm->importCallback,
  584|  4.16k|                                              vm->importCallbackContext,
  585|  4.16k|                                              vm->stringOutput);
  586|  4.16k|                size_t sz = 1;  // final sentinel
  587|   188k|                for (const auto &doc : documents) {
  ------------------
  |  Branch (587:38): [True: 188k, False: 4.16k]
  ------------------
  588|   188k|                    sz += doc.length() + 2;  // Add a '\n' as well as sentinel
  589|   188k|                }
  590|  4.16k|                char *buf = (char *)::malloc(sz);
  591|  4.16k|                if (buf == nullptr)
  ------------------
  |  Branch (591:21): [True: 0, False: 4.16k]
  ------------------
  592|      0|                    memory_panic();
  593|  4.16k|                std::ptrdiff_t i = 0;
  594|   188k|                for (const auto &doc : documents) {
  ------------------
  |  Branch (594:38): [True: 188k, False: 4.16k]
  ------------------
  595|   188k|                    memcpy(&buf[i], doc.c_str(), doc.length());
  596|   188k|                    i += doc.length();
  597|   188k|                    buf[i] = '\n';
  598|   188k|                    i++;
  599|   188k|                    buf[i] = '\0';
  600|   188k|                    i++;
  601|   188k|                }
  602|  4.16k|                buf[i] = '\0';  // final sentinel
  603|  4.16k|                *error = false;
  604|  4.16k|                return buf;
  605|      0|            } break;
  606|       |
  607|      0|            default:
  ------------------
  |  Branch (607:13): [True: 0, False: 9.27k]
  ------------------
  608|      0|                fputs("INTERNAL ERROR: bad value of 'kind', probably memory corruption.\n", stderr);
  609|      0|                abort();
  610|  9.27k|        }
  611|       |
  612|  9.27k|    } catch (StaticError &e) {
  613|  5.10k|        std::stringstream ss;
  614|  5.10k|        ss << "STATIC ERROR: " << e << std::endl;
  615|  5.10k|        *error = true;
  616|  5.10k|        return from_string(vm, ss.str());
  617|       |
  618|  5.10k|    } catch (RuntimeError &e) {
  619|  3.45k|        std::stringstream ss;
  620|  3.45k|        ss << "RUNTIME ERROR: " << e.msg << std::endl;
  621|  3.45k|        const long max_above = vm->maxTrace / 2;
  622|  3.45k|        const long max_below = vm->maxTrace - max_above;
  623|  3.45k|        const long sz = e.stackTrace.size();
  624|   270k|        for (long i = 0; i < sz; ++i) {
  ------------------
  |  Branch (624:26): [True: 267k, False: 3.45k]
  ------------------
  625|   267k|            const auto &f = e.stackTrace[i];
  626|   267k|            if (vm->maxTrace > 0 && i >= max_above && i < sz - max_below) {
  ------------------
  |  Branch (626:17): [True: 267k, False: 0]
  |  Branch (626:37): [True: 253k, False: 13.6k]
  |  Branch (626:55): [True: 245k, False: 8.46k]
  ------------------
  627|   245k|                if (i == max_above)
  ------------------
  |  Branch (627:21): [True: 718, False: 244k]
  ------------------
  628|    718|                    ss << "\t..." << std::endl;
  629|   245k|            } else {
  630|  22.0k|                ss << "\t" << f.location << "\t" << f.name << std::endl;
  631|  22.0k|            }
  632|   267k|        }
  633|  3.45k|        *error = true;
  634|  3.45k|        return from_string(vm, ss.str());
  635|  3.45k|    }
  636|       |
  637|      0|    return nullptr;  // Quiet, compiler.
  638|  9.27k|}

_ZN7jsonnet8internal22jsonnet_unparse_numberEd:
   37|  1.64M|{
   38|  1.64M|    std::stringstream ss;
   39|  1.64M|    if (v == floor(v)) {
  ------------------
  |  Branch (39:9): [True: 1.63M, False: 7.21k]
  ------------------
   40|  1.63M|        ss << std::fixed << std::setprecision(0) << v;
   41|  1.63M|    } else {
   42|       |        // See "What Every Computer Scientist Should Know About Floating-Point Arithmetic"
   43|       |        // Theorem 15
   44|       |        // https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
   45|  7.21k|        ss << std::setprecision(17);
   46|  7.21k|        ss << v;
   47|  7.21k|    }
   48|  1.64M|    return ss.str();
   49|  1.64M|}
_ZN7jsonnet8internal13jsonnet_parseEPNS0_9AllocatorERNSt3__14listINS0_5TokenENS3_9allocatorIS5_EEEE:
 1123|  17.9k|{
 1124|  17.9k|    Parser parser(tokens, alloc);
 1125|  17.9k|    AST *expr = parser.parse(MAX_PRECEDENCE);
 1126|  17.9k|    if (tokens.front().kind != Token::END_OF_FILE) {
  ------------------
  |  Branch (1126:9): [True: 260, False: 17.6k]
  ------------------
 1127|    260|        std::stringstream ss;
 1128|    260|        ss << "did not expect: " << tokens.front();
 1129|    260|        throw StaticError(tokens.front().location, ss.str());
 1130|    260|    }
 1131|       |
 1132|  17.6k|    return expr;
 1133|  17.9k|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16ParserC2ERNSt3__14listINS0_5TokenENS3_9allocatorIS5_EEEEPNS0_9AllocatorE:
  145|  17.9k|    Parser(Tokens &tokens, Allocator *alloc) : tokens(tokens), alloc(alloc) {}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser5parseEj:
  909|  51.0M|    {
  910|  51.0M|        AST *ast = maybeParseGreedy();
  911|       |        // There cannot be an operator after a greedy parse.
  912|  51.0M|        if (ast != nullptr) return ast;
  ------------------
  |  Branch (912:13): [True: 6.38M, False: 44.6M]
  ------------------
  913|       |
  914|       |        // If we get here, we could be parsing an infix construct.
  915|       |
  916|       |        // Allocate this on the heap to control stack growth.
  917|  44.6M|        std::unique_ptr<Token> begin_(new Token(peek()));
  918|  44.6M|        const Token &begin = *begin_;
  919|       |
  920|  44.6M|        AST *lhs = parseTerminalBracketsOrUnary();
  921|       |
  922|  44.6M|        return parseInfix(lhs, begin, max_precedence);
  923|  51.0M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser16maybeParseGreedyEv:
  749|  51.0M|    {
  750|       |        // Allocate this on the heap to control stack growth.
  751|  51.0M|        std::unique_ptr<Token> begin_(new Token(peek()));
  752|  51.0M|        const Token &begin = *begin_;
  753|       |
  754|  51.0M|        switch (begin.kind) {
  755|       |            // These cases have effectively MAX_PRECEDENCE as the first
  756|       |            // call to parse will parse them.
  757|   381k|            case Token::ASSERT: {
  ------------------
  |  Branch (757:13): [True: 381k, False: 50.6M]
  ------------------
  758|   381k|                pop();
  759|   381k|                AST *cond = parse(MAX_PRECEDENCE);
  760|   381k|                Fodder colonFodder;
  761|   381k|                AST *msg = nullptr;
  762|   381k|                if (peek().kind == Token::OPERATOR && peek().data == ":") {
  ------------------
  |  Branch (762:21): [True: 352k, False: 28.4k]
  |  Branch (762:55): [True: 352k, False: 1]
  ------------------
  763|   352k|                    Token colon = pop();
  764|   352k|                    colonFodder = colon.fodder;
  765|   352k|                    msg = parse(MAX_PRECEDENCE);
  766|   352k|                }
  767|   381k|                Token semicolon = popExpect(Token::SEMICOLON);
  768|   381k|                AST *rest = parse(MAX_PRECEDENCE);
  769|   381k|                return alloc->make<Assert>(span(begin, rest),
  770|   381k|                                           begin.fodder,
  771|   381k|                                           cond,
  772|   381k|                                           colonFodder,
  773|   381k|                                           msg,
  774|   381k|                                           semicolon.fodder,
  775|   381k|                                           rest);
  776|      0|            }
  777|       |
  778|   588k|            case Token::ERROR: {
  ------------------
  |  Branch (778:13): [True: 588k, False: 50.4M]
  ------------------
  779|   588k|                pop();
  780|   588k|                AST *expr = parse(MAX_PRECEDENCE);
  781|   588k|                return alloc->make<Error>(span(begin, expr), begin.fodder, expr);
  782|      0|            }
  783|       |
  784|  2.98M|            case Token::IF: {
  ------------------
  |  Branch (784:13): [True: 2.98M, False: 48.0M]
  ------------------
  785|  2.98M|                pop();
  786|  2.98M|                AST *cond = parse(MAX_PRECEDENCE);
  787|  2.98M|                Token then = popExpect(Token::THEN);
  788|  2.98M|                AST *branch_true = parse(MAX_PRECEDENCE);
  789|  2.98M|                if (peek().kind == Token::ELSE) {
  ------------------
  |  Branch (789:21): [True: 2.95M, False: 37.7k]
  ------------------
  790|  2.95M|                    Token else_ = pop();
  791|  2.95M|                    AST *branch_false = parse(MAX_PRECEDENCE);
  792|  2.95M|                    return alloc->make<Conditional>(span(begin, branch_false),
  793|  2.95M|                                                    begin.fodder,
  794|  2.95M|                                                    cond,
  795|  2.95M|                                                    then.fodder,
  796|  2.95M|                                                    branch_true,
  797|  2.95M|                                                    else_.fodder,
  798|  2.95M|                                                    branch_false);
  799|  2.95M|                }
  800|  37.7k|                return alloc->make<Conditional>(span(begin, branch_true),
  801|  37.7k|                                                begin.fodder,
  802|  37.7k|                                                cond,
  803|  37.7k|                                                then.fodder,
  804|  37.7k|                                                branch_true,
  805|  37.7k|                                                Fodder{},
  806|  37.7k|                                                nullptr);
  807|  2.98M|            }
  808|       |
  809|   196k|            case Token::FUNCTION: {
  ------------------
  |  Branch (809:13): [True: 196k, False: 50.8M]
  ------------------
  810|   196k|                pop();  // Still available in 'begin'.
  811|   196k|                Token paren_l = pop();
  812|   196k|                if (paren_l.kind == Token::PAREN_L) {
  ------------------
  |  Branch (812:21): [True: 196k, False: 4]
  ------------------
  813|   196k|                    std::vector<AST *> params_asts;
  814|   196k|                    bool got_comma;
  815|   196k|                    Fodder paren_r_fodder;
  816|   196k|                    ArgParams params = parseParams("function parameter", got_comma, paren_r_fodder);
  817|   196k|                    AST *body = parse(MAX_PRECEDENCE);
  818|   196k|                    return alloc->make<Function>(span(begin, body),
  819|   196k|                                                 begin.fodder,
  820|   196k|                                                 paren_l.fodder,
  821|   196k|                                                 params,
  822|   196k|                                                 got_comma,
  823|   196k|                                                 paren_r_fodder,
  824|   196k|                                                 body);
  825|   196k|                } else {
  826|      4|                    std::stringstream ss;
  827|      4|                    ss << "expected ( but got " << paren_l;
  828|      4|                    throw StaticError(paren_l.location, ss.str());
  829|      4|                }
  830|   196k|            }
  831|       |
  832|    642|            case Token::IMPORT: {
  ------------------
  |  Branch (832:13): [True: 642, False: 51.0M]
  ------------------
  833|    642|                pop();
  834|    642|                AST *body = parse(MAX_PRECEDENCE);
  835|    642|                if (body->type == AST_LITERAL_STRING) {
  ------------------
  |  Branch (835:21): [True: 440, False: 202]
  ------------------
  836|    440|                    auto *lit = static_cast<LiteralString *>(body);
  837|    440|                    if (lit->tokenKind == LiteralString::BLOCK) {
  ------------------
  |  Branch (837:25): [True: 1, False: 439]
  ------------------
  838|      1|                        throw StaticError(lit->location,
  839|      1|                                          "Cannot use text blocks in import statements.");
  840|      1|                    }
  841|    439|                    return alloc->make<Import>(span(begin, body), begin.fodder, lit);
  842|    440|                } else {
  843|    202|                    std::stringstream ss;
  844|    202|                    ss << "computed imports are not allowed.";
  845|    202|                    throw StaticError(body->location, ss.str());
  846|    202|                }
  847|    642|            }
  848|       |
  849|  3.46k|            case Token::IMPORTSTR: {
  ------------------
  |  Branch (849:13): [True: 3.46k, False: 51.0M]
  ------------------
  850|  3.46k|                pop();
  851|  3.46k|                AST *body = parse(MAX_PRECEDENCE);
  852|  3.46k|                if (body->type == AST_LITERAL_STRING) {
  ------------------
  |  Branch (852:21): [True: 3.25k, False: 208]
  ------------------
  853|  3.25k|                    auto *lit = static_cast<LiteralString *>(body);
  854|  3.25k|                    if (lit->tokenKind == LiteralString::BLOCK) {
  ------------------
  |  Branch (854:25): [True: 0, False: 3.25k]
  ------------------
  855|      0|                        throw StaticError(lit->location,
  856|      0|                                          "Cannot use text blocks in import statements.");
  857|      0|                    }
  858|  3.25k|                    return alloc->make<Importstr>(span(begin, body), begin.fodder, lit);
  859|  3.25k|                } else {
  860|    208|                    std::stringstream ss;
  861|    208|                    ss << "computed imports are not allowed.";
  862|    208|                    throw StaticError(body->location, ss.str());
  863|    208|                }
  864|  3.46k|            }
  865|       |
  866|    453|            case Token::IMPORTBIN: {
  ------------------
  |  Branch (866:13): [True: 453, False: 51.0M]
  ------------------
  867|    453|                pop();
  868|    453|                AST *body = parse(MAX_PRECEDENCE);
  869|    453|                if (body->type == AST_LITERAL_STRING) {
  ------------------
  |  Branch (869:21): [True: 209, False: 244]
  ------------------
  870|    209|                    auto *lit = static_cast<LiteralString *>(body);
  871|    209|                    if (lit->tokenKind == LiteralString::BLOCK) {
  ------------------
  |  Branch (871:25): [True: 0, False: 209]
  ------------------
  872|      0|                        throw StaticError(lit->location,
  873|      0|                                          "Cannot use text blocks in import statements.");
  874|      0|                    }
  875|    209|                    return alloc->make<Importbin>(span(begin, body), begin.fodder, lit);
  876|    244|                } else {
  877|    244|                    std::stringstream ss;
  878|    244|                    ss << "computed imports are not allowed.";
  879|    244|                    throw StaticError(body->location, ss.str());
  880|    244|                }
  881|    453|            }
  882|       |
  883|  2.22M|            case Token::LOCAL: {
  ------------------
  |  Branch (883:13): [True: 2.22M, False: 48.8M]
  ------------------
  884|  2.22M|                pop();
  885|  2.22M|                Local::Binds binds;
  886|  2.35M|                do {
  887|  2.35M|                    Token delim = parseBind(binds);
  888|  2.35M|                    if (delim.kind != Token::SEMICOLON && delim.kind != Token::COMMA) {
  ------------------
  |  Branch (888:25): [True: 123k, False: 2.22M]
  |  Branch (888:59): [True: 24, False: 123k]
  ------------------
  889|     24|                        std::stringstream ss;
  890|     24|                        ss << "expected , or ; but got " << delim;
  891|     24|                        throw StaticError(delim.location, ss.str());
  892|     24|                    }
  893|  2.35M|                    if (delim.kind == Token::SEMICOLON)
  ------------------
  |  Branch (893:25): [True: 2.22M, False: 123k]
  ------------------
  894|  2.22M|                        break;
  895|  2.35M|                } while (true);
  ------------------
  |  Branch (895:26): [Folded - Ignored]
  ------------------
  896|  2.22M|                AST *body = parse(MAX_PRECEDENCE);
  897|  2.22M|                return alloc->make<Local>(span(begin, body), begin.fodder, binds, body);
  898|  2.22M|            }
  899|       |
  900|  44.6M|            default:
  ------------------
  |  Branch (900:13): [True: 44.6M, False: 6.38M]
  ------------------
  901|  44.6M|            return nullptr;
  902|  51.0M|        }
  903|  51.0M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser3popEv:
  101|   130M|    {
  102|   130M|        Token tok = peek();
  103|   130M|        tokens.pop_front();
  104|   130M|        return tok;
  105|   130M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser9popExpectENS0_5Token4KindEPKc:
  126|  19.8M|    {
  127|  19.8M|        Token tok = pop();
  128|  19.8M|        if (tok.kind != k) {
  ------------------
  |  Branch (128:13): [True: 325, False: 19.8M]
  ------------------
  129|    325|            std::stringstream ss;
  130|    325|            ss << "expected token " << k << " but got " << tok;
  131|    325|            throw StaticError(tok.location, ss.str());
  132|    325|        }
  133|  19.8M|        if (data != nullptr && tok.data != data) {
  ------------------
  |  Branch (133:13): [True: 2.41M, False: 17.4M]
  |  Branch (133:32): [True: 11, False: 2.41M]
  ------------------
  134|     11|            std::stringstream ss;
  135|     11|            ss << "expected operator " << data << " but got " << tok.data;
  136|     11|            throw StaticError(tok.location, ss.str());
  137|     11|        }
  138|  19.8M|        return tok;
  139|  19.8M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14spanERKNS0_5TokenEPNS0_3ASTE:
   84|  15.3M|{
   85|  15.3M|    return LocationRange(begin.location.file, begin.location.begin, end->location.end);
   86|  15.3M|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser11parseParamsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERbRNS3_6vectorINS0_13FodderElementENS7_ISE_EEEE:
  199|  2.03M|    {
  200|  2.03M|        ArgParams params;
  201|  2.03M|        Token paren_r = parseArgs(params, element_kind, got_comma);
  202|       |
  203|       |        // Check they're all identifiers
  204|       |        // parseArgs returns f(x) with x as an expression.  Convert it here.
  205|  3.99M|        for (auto &p : params) {
  ------------------
  |  Branch (205:22): [True: 3.99M, False: 2.03M]
  ------------------
  206|  3.99M|            if (p.id == nullptr) {
  ------------------
  |  Branch (206:17): [True: 3.79M, False: 195k]
  ------------------
  207|  3.79M|                if (p.expr->type != AST_VAR) {
  ------------------
  |  Branch (207:21): [True: 2, False: 3.79M]
  ------------------
  208|      2|                    throw StaticError(p.expr->location, "could not parse parameter here.");
  209|      2|                }
  210|  3.79M|                auto *pv = static_cast<Var *>(p.expr);
  211|  3.79M|                p.id = pv->id;
  212|  3.79M|                p.idFodder = pv->openFodder;
  213|  3.79M|                p.expr = nullptr;
  214|  3.79M|            }
  215|  3.99M|        }
  216|       |
  217|  2.03M|        close_fodder = paren_r.fodder;
  218|       |
  219|  2.03M|        return params;
  220|  2.03M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser9parseArgsERNSt3__16vectorINS0_8ArgParamENS3_9allocatorIS5_EEEERKNS3_12basic_stringIcNS3_11char_traitsIcEENS6_IcEEEERb:
  156|  9.51M|    {
  157|  9.51M|        got_comma = false;
  158|  9.51M|        bool first = true;
  159|  26.5M|        do {
  160|  26.5M|            Token next = peek();
  161|  26.5M|            if (next.kind == Token::PAREN_R) {
  ------------------
  |  Branch (161:17): [True: 9.51M, False: 17.0M]
  ------------------
  162|       |                // got_comma can be true or false here.
  163|  9.51M|                return pop();
  164|  9.51M|            }
  165|  17.0M|            if (!first && !got_comma) {
  ------------------
  |  Branch (165:17): [True: 7.50M, False: 9.51M]
  |  Branch (165:27): [True: 114, False: 7.50M]
  ------------------
  166|    114|                std::stringstream ss;
  167|    114|                ss << "expected a comma before next " << element_kind << ".";
  168|    114|                throw StaticError(next.location, ss.str());
  169|    114|            }
  170|       |            // Either id=expr or id or expr, but note that expr could be id==1 so this needs
  171|       |            // look-ahead.
  172|  17.0M|            Fodder id_fodder;
  173|  17.0M|            const Identifier *id = nullptr;
  174|  17.0M|            Fodder eq_fodder;
  175|  17.0M|            if (peek().kind == Token::IDENTIFIER) {
  ------------------
  |  Branch (175:17): [True: 14.2M, False: 2.79M]
  ------------------
  176|  14.2M|                Token maybe_eq = doublePeek();
  177|  14.2M|                if (maybe_eq.kind == Token::OPERATOR && maybe_eq.data == "=") {
  ------------------
  |  Branch (177:21): [True: 1.47M, False: 12.7M]
  |  Branch (177:57): [True: 224k, False: 1.25M]
  ------------------
  178|   224k|                    id_fodder = peek().fodder;
  179|   224k|                    id = alloc->makeIdentifier(peek().data32());
  180|   224k|                    eq_fodder = maybe_eq.fodder;
  181|   224k|                    pop();  // id
  182|   224k|                    pop();  // eq
  183|   224k|                }
  184|  14.2M|            }
  185|  17.0M|            AST *expr = parse(MAX_PRECEDENCE);
  186|  17.0M|            got_comma = false;
  187|  17.0M|            first = false;
  188|  17.0M|            Fodder comma_fodder;
  189|  17.0M|            if (peek().kind == Token::COMMA) {
  ------------------
  |  Branch (189:17): [True: 7.50M, False: 9.51M]
  ------------------
  190|  7.50M|                Token comma = pop();
  191|  7.50M|                comma_fodder = comma.fodder;
  192|  7.50M|                got_comma = true;
  193|  7.50M|            }
  194|  17.0M|            args.emplace_back(id_fodder, id, eq_fodder, expr, comma_fodder);
  195|  17.0M|        } while (true);
  ------------------
  |  Branch (195:18): [Folded - Ignored]
  ------------------
  196|  9.51M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser10doublePeekEv:
  119|  14.2M|    {
  120|  14.2M|        Tokens::iterator it = tokens.begin();  // First one.
  121|  14.2M|        it++;                                  // Now pointing at the second one.
  122|  14.2M|        return *(it);
  123|  14.2M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser9parseBindERNSt3__16vectorINS0_5Local4BindENS3_9allocatorIS6_EEEE:
  223|  2.35M|    {
  224|  2.35M|        Token var_id = popExpect(Token::IDENTIFIER);
  225|  2.35M|        auto *id = alloc->makeIdentifier(var_id.data32());
  226|  2.35M|        for (const auto &bind : binds) {
  ------------------
  |  Branch (226:31): [True: 331k, False: 2.35M]
  ------------------
  227|   331k|            if (bind.var == id)
  ------------------
  |  Branch (227:17): [True: 4, False: 331k]
  ------------------
  228|      4|                throw StaticError(var_id.location, "duplicate local var: " + var_id.data);
  229|   331k|        }
  230|  2.35M|        bool is_function = false;
  231|  2.35M|        ArgParams params;
  232|  2.35M|        bool trailing_comma = false;
  233|  2.35M|        Fodder fodder_l, fodder_r;
  234|  2.35M|        if (peek().kind == Token::PAREN_L) {
  ------------------
  |  Branch (234:13): [True: 706k, False: 1.64M]
  ------------------
  235|   706k|            Token paren_l = pop();
  236|   706k|            fodder_l = paren_l.fodder;
  237|   706k|            params = parseParams("function parameter", trailing_comma, fodder_r);
  238|   706k|            is_function = true;
  239|   706k|        }
  240|  2.35M|        Token eq = popExpect(Token::OPERATOR, "=");
  241|  2.35M|        AST *body = parse(MAX_PRECEDENCE);
  242|  2.35M|        Token delim = pop();
  243|  2.35M|        binds.emplace_back(var_id.fodder,
  244|  2.35M|                           id,
  245|  2.35M|                           eq.fodder,
  246|  2.35M|                           body,
  247|  2.35M|                           is_function,
  248|  2.35M|                           fodder_l,
  249|  2.35M|                           params,
  250|  2.35M|                           trailing_comma,
  251|  2.35M|                           fodder_r,
  252|  2.35M|                           delim.fodder);
  253|  2.35M|        return delim;
  254|  2.35M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser4peekEv:
  113|   419M|    {
  114|   419M|        return tokens.front();
  115|   419M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser28parseTerminalBracketsOrUnaryEv:
  573|  44.6M|    {
  574|  44.6M|        Token tok = pop();
  575|  44.6M|        switch (tok.kind) {
  ------------------
  |  Branch (575:17): [True: 0, False: 44.6M]
  ------------------
  576|      0|            case Token::ASSERT:
  ------------------
  |  Branch (576:13): [True: 0, False: 44.6M]
  ------------------
  577|     10|            case Token::BRACE_R:
  ------------------
  |  Branch (577:13): [True: 10, False: 44.6M]
  ------------------
  578|     25|            case Token::BRACKET_R:
  ------------------
  |  Branch (578:13): [True: 15, False: 44.6M]
  ------------------
  579|     59|            case Token::COMMA:
  ------------------
  |  Branch (579:13): [True: 34, False: 44.6M]
  ------------------
  580|     77|            case Token::DOT:
  ------------------
  |  Branch (580:13): [True: 18, False: 44.6M]
  ------------------
  581|     78|            case Token::ELSE:
  ------------------
  |  Branch (581:13): [True: 1, False: 44.6M]
  ------------------
  582|     78|            case Token::ERROR:
  ------------------
  |  Branch (582:13): [True: 0, False: 44.6M]
  ------------------
  583|     79|            case Token::FOR:
  ------------------
  |  Branch (583:13): [True: 1, False: 44.6M]
  ------------------
  584|     79|            case Token::FUNCTION:
  ------------------
  |  Branch (584:13): [True: 0, False: 44.6M]
  ------------------
  585|     79|            case Token::IF:
  ------------------
  |  Branch (585:13): [True: 0, False: 44.6M]
  ------------------
  586|     91|            case Token::IN:
  ------------------
  |  Branch (586:13): [True: 12, False: 44.6M]
  ------------------
  587|     91|            case Token::IMPORT:
  ------------------
  |  Branch (587:13): [True: 0, False: 44.6M]
  ------------------
  588|     91|            case Token::IMPORTSTR:
  ------------------
  |  Branch (588:13): [True: 0, False: 44.6M]
  ------------------
  589|     91|            case Token::IMPORTBIN:
  ------------------
  |  Branch (589:13): [True: 0, False: 44.6M]
  ------------------
  590|     91|            case Token::LOCAL:
  ------------------
  |  Branch (590:13): [True: 0, False: 44.6M]
  ------------------
  591|    111|            case Token::PAREN_R:
  ------------------
  |  Branch (591:13): [True: 20, False: 44.6M]
  ------------------
  592|    119|            case Token::SEMICOLON:
  ------------------
  |  Branch (592:13): [True: 8, False: 44.6M]
  ------------------
  593|    121|            case Token::TAILSTRICT:
  ------------------
  |  Branch (593:13): [True: 2, False: 44.6M]
  ------------------
  594|    123|            case Token::THEN: throw unexpected(tok, "parsing terminal");
  ------------------
  |  Branch (594:13): [True: 2, False: 44.6M]
  ------------------
  595|       |
  596|    821|            case Token::END_OF_FILE: throw StaticError(tok.location, "unexpected end of file.");
  ------------------
  |  Branch (596:13): [True: 821, False: 44.6M]
  ------------------
  597|       |
  598|   989k|            case Token::OPERATOR: {
  ------------------
  |  Branch (598:13): [True: 989k, False: 43.6M]
  ------------------
  599|   989k|                UnaryOp uop;
  600|   989k|                if (!op_is_unary(tok.data, uop)) {
  ------------------
  |  Branch (600:21): [True: 254, False: 989k]
  ------------------
  601|    254|                    std::stringstream ss;
  602|    254|                    ss << "not a unary operator: " << tok.data;
  603|    254|                    throw StaticError(tok.location, ss.str());
  604|    254|                }
  605|   989k|                AST *expr = parse(UNARY_PRECEDENCE);
  606|   989k|                return alloc->make<Unary>(span(tok, expr), tok.fodder, uop, expr);
  607|   989k|            }
  608|   447k|            case Token::BRACE_L: {
  ------------------
  |  Branch (608:13): [True: 447k, False: 44.2M]
  ------------------
  609|   447k|                AST *obj;
  610|   447k|                parseObjectRemainder(obj, tok);
  611|   447k|                return obj;
  612|   989k|            }
  613|       |
  614|  1.27M|            case Token::BRACKET_L: {
  ------------------
  |  Branch (614:13): [True: 1.27M, False: 43.4M]
  ------------------
  615|  1.27M|                Token next = peek();
  616|  1.27M|                if (next.kind == Token::BRACKET_R) {
  ------------------
  |  Branch (616:21): [True: 207k, False: 1.06M]
  ------------------
  617|   207k|                    Token bracket_r = pop();
  618|   207k|                    return alloc->make<Array>(
  619|   207k|                        span(tok, next), tok.fodder, Array::Elements{}, false, bracket_r.fodder);
  620|   207k|                }
  621|  1.06M|                AST *first = parse(MAX_PRECEDENCE);
  622|  1.06M|                bool got_comma = false;
  623|  1.06M|                Fodder comma_fodder;
  624|  1.06M|                next = peek();
  625|  1.06M|                if (!got_comma && next.kind == Token::COMMA) {
  ------------------
  |  Branch (625:21): [True: 1.06M, False: 2.72k]
  |  Branch (625:35): [True: 149k, False: 910k]
  ------------------
  626|   149k|                    Token comma = pop();
  627|   149k|                    comma_fodder = comma.fodder;
  628|   149k|                    next = peek();
  629|   149k|                    got_comma = true;
  630|   149k|                }
  631|       |
  632|  1.06M|                if (next.kind == Token::FOR) {
  ------------------
  |  Branch (632:21): [True: 307k, False: 755k]
  ------------------
  633|       |                    // It's a comprehension
  634|   307k|                    Token for_token = pop();
  635|   307k|                    std::vector<ComprehensionSpec> specs;
  636|   307k|                    Token last = parseComprehensionSpecs(Token::BRACKET_R, for_token.fodder, specs);
  637|   307k|                    return alloc->make<ArrayComprehension>(span(tok, last),
  638|   307k|                                                           tok.fodder,
  639|   307k|                                                           first,
  640|   307k|                                                           comma_fodder,
  641|   307k|                                                           got_comma,
  642|   307k|                                                           specs,
  643|   307k|                                                           last.fodder);
  644|   307k|                }
  645|       |
  646|       |                // Not a comprehension: It can have more elements.
  647|   755k|                Array::Elements elements;
  648|   755k|                elements.emplace_back(first, comma_fodder);
  649|  4.00M|                do {
  650|  4.00M|                    if (next.kind == Token::BRACKET_R) {
  ------------------
  |  Branch (650:25): [True: 751k, False: 3.25M]
  ------------------
  651|   751k|                        Token bracket_r = pop();
  652|   751k|                        return alloc->make<Array>(
  653|   751k|                            span(tok, next), tok.fodder, elements, got_comma, bracket_r.fodder);
  654|   751k|                    }
  655|  3.25M|                    if (!got_comma) {
  ------------------
  |  Branch (655:25): [True: 310, False: 3.25M]
  ------------------
  656|    310|                        std::stringstream ss;
  657|    310|                        ss << "expected a comma before next array element.";
  658|    310|                        throw StaticError(next.location, ss.str());
  659|    310|                    }
  660|  3.25M|                    AST *expr = parse(MAX_PRECEDENCE);
  661|  3.25M|                    comma_fodder.clear();
  662|  3.25M|                    got_comma = false;
  663|  3.25M|                    next = peek();
  664|  3.25M|                    if (next.kind == Token::COMMA) {
  ------------------
  |  Branch (664:25): [True: 3.12M, False: 132k]
  ------------------
  665|  3.12M|                        Token comma = pop();
  666|  3.12M|                        comma_fodder = comma.fodder;
  667|  3.12M|                        next = peek();
  668|  3.12M|                        got_comma = true;
  669|  3.12M|                    }
  670|  3.25M|                    elements.emplace_back(expr, comma_fodder);
  671|  3.25M|                } while (true);
  ------------------
  |  Branch (671:26): [Folded - Ignored]
  ------------------
  672|   755k|            }
  673|       |
  674|   451k|            case Token::PAREN_L: {
  ------------------
  |  Branch (674:13): [True: 447k, False: 44.2M]
  ------------------
  675|   451k|                auto *inner = parse(MAX_PRECEDENCE);
  676|   451k|                Token close = popExpect(Token::PAREN_R);
  677|   451k|                return alloc->make<Parens>(span(tok, close), tok.fodder, inner, close.fodder);
  678|   755k|            }
  679|       |
  680|       |            // Literals
  681|  6.99M|            case Token::NUMBER: return alloc->make<LiteralNumber>(span(tok), tok.fodder, tok.data);
  ------------------
  |  Branch (681:13): [True: 6.99M, False: 37.6M]
  ------------------
  682|       |
  683|  4.33M|            case Token::STRING_SINGLE:
  ------------------
  |  Branch (683:13): [True: 4.33M, False: 40.3M]
  ------------------
  684|  4.33M|                return alloc->make<LiteralString>(
  685|  4.33M|                    span(tok), tok.fodder, tok.data32(), LiteralString::SINGLE, "", "");
  686|  73.3k|            case Token::STRING_DOUBLE:
  ------------------
  |  Branch (686:13): [True: 73.3k, False: 44.6M]
  ------------------
  687|  73.3k|                return alloc->make<LiteralString>(
  688|  73.3k|                    span(tok), tok.fodder, tok.data32(), LiteralString::DOUBLE, "", "");
  689|  3.28k|            case Token::STRING_BLOCK:
  ------------------
  |  Branch (689:13): [True: 3.28k, False: 44.6M]
  ------------------
  690|  3.28k|                return alloc->make<LiteralString>(span(tok),
  691|  3.28k|                                                  tok.fodder,
  692|  3.28k|                                                  tok.data32(),
  693|  3.28k|                                                  LiteralString::BLOCK,
  694|  3.28k|                                                  tok.stringBlockIndent,
  695|  3.28k|                                                  tok.stringBlockTermIndent);
  696|  1.58k|            case Token::VERBATIM_STRING_SINGLE:
  ------------------
  |  Branch (696:13): [True: 1.58k, False: 44.6M]
  ------------------
  697|  1.58k|                return alloc->make<LiteralString>(
  698|  1.58k|                    span(tok), tok.fodder, tok.data32(), LiteralString::VERBATIM_SINGLE, "", "");
  699|    949|            case Token::VERBATIM_STRING_DOUBLE:
  ------------------
  |  Branch (699:13): [True: 949, False: 44.6M]
  ------------------
  700|    949|                return alloc->make<LiteralString>(
  701|    949|                    span(tok), tok.fodder, tok.data32(), LiteralString::VERBATIM_DOUBLE, "", "");
  702|       |
  703|   455k|            case Token::FALSE: return alloc->make<LiteralBoolean>(span(tok), tok.fodder, false);
  ------------------
  |  Branch (703:13): [True: 455k, False: 44.2M]
  ------------------
  704|       |
  705|   334k|            case Token::TRUE: return alloc->make<LiteralBoolean>(span(tok), tok.fodder, true);
  ------------------
  |  Branch (705:13): [True: 334k, False: 44.3M]
  ------------------
  706|       |
  707|   160k|            case Token::NULL_LIT: return alloc->make<LiteralNull>(span(tok), tok.fodder);
  ------------------
  |  Branch (707:13): [True: 160k, False: 44.5M]
  ------------------
  708|       |
  709|       |            // Variables
  710|  41.9k|            case Token::DOLLAR: return alloc->make<Dollar>(span(tok), tok.fodder);
  ------------------
  |  Branch (710:13): [True: 41.9k, False: 44.6M]
  ------------------
  711|       |
  712|  29.0M|            case Token::IDENTIFIER:
  ------------------
  |  Branch (712:13): [True: 29.0M, False: 15.6M]
  ------------------
  713|  29.0M|                return alloc->make<Var>(span(tok), tok.fodder, alloc->makeIdentifier(tok.data32()));
  714|       |
  715|  38.8k|            case Token::SELF: return alloc->make<Self>(span(tok), tok.fodder);
  ------------------
  |  Branch (715:13): [True: 38.8k, False: 44.6M]
  ------------------
  716|       |
  717|  8.54k|            case Token::SUPER: {
  ------------------
  |  Branch (717:13): [True: 8.54k, False: 44.6M]
  ------------------
  718|  8.54k|                Token next = pop();
  719|  8.54k|                AST *index = nullptr;
  720|  8.54k|                const Identifier *id = nullptr;
  721|  8.54k|                Fodder id_fodder;
  722|  8.54k|                switch (next.kind) {
  723|  7.98k|                    case Token::DOT: {
  ------------------
  |  Branch (723:21): [True: 7.98k, False: 558]
  ------------------
  724|  7.98k|                        Token field_id = popExpect(Token::IDENTIFIER);
  725|  7.98k|                        id_fodder = field_id.fodder;
  726|  7.98k|                        id = alloc->makeIdentifier(field_id.data32());
  727|  7.98k|                    } break;
  728|    552|                    case Token::BRACKET_L: {
  ------------------
  |  Branch (728:21): [True: 552, False: 7.98k]
  ------------------
  729|    552|                        index = parse(MAX_PRECEDENCE);
  730|    552|                        Token bracket_r = popExpect(Token::BRACKET_R);
  731|    552|                        id_fodder = bracket_r.fodder;  // Not id_fodder, but use the same var.
  732|    552|                    } break;
  733|      6|                    default: throw StaticError(tok.location, "expected . or [ after super.");
  ------------------
  |  Branch (733:21): [True: 6, False: 8.53k]
  ------------------
  734|  8.54k|                }
  735|  8.22k|                return alloc->make<SuperIndex>(
  736|  8.22k|                    span(tok), tok.fodder, next.fodder, index, id_fodder, id);
  737|  8.54k|            }
  738|  44.6M|        }
  739|       |
  740|      0|        std::cerr << "INTERNAL ERROR: Unknown tok kind: " << tok.kind << std::endl;
  741|      0|        std::abort();
  742|      0|        return nullptr;  // Quiet, compiler.
  743|  44.6M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser10unexpectedERKNS0_5TokenERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
   94|    431|    {
   95|    431|        std::stringstream ss;
   96|    431|        ss << "unexpected: " << tok.kind << " while " << while_;
   97|    431|        return StaticError(tok.location, ss.str());
   98|    431|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111op_is_unaryERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERNS0_7UnaryOpE:
   56|   989k|{
   57|   989k|    auto it = unary_map.find(op);
   58|   989k|    if (it == unary_map.end())
  ------------------
  |  Branch (58:9): [True: 254, False: 989k]
  ------------------
   59|    254|        return false;
   60|   989k|    uop = it->second;
   61|   989k|    return true;
   62|   989k|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser20parseObjectRemainderERPNS0_3ASTERKNS0_5TokenE:
  257|   533k|    {
  258|   533k|        ObjectFields fields;
  259|   533k|        std::set<std::string> literal_fields;  // For duplicate fields detection.
  260|   533k|        std::set<const Identifier *> binds;    // For duplicate locals detection.
  261|       |
  262|   533k|        bool got_comma = false;
  263|   533k|        bool first = true;
  264|   533k|        Token next = pop();
  265|       |
  266|  2.79M|        do {
  267|  2.79M|            if (next.kind == Token::BRACE_R) {
  ------------------
  |  Branch (267:17): [True: 480k, False: 2.31M]
  ------------------
  268|   480k|                obj = alloc->make<Object>(
  269|   480k|                    span(tok, next), tok.fodder, fields, got_comma, next.fodder);
  270|   480k|                return next;
  271|       |
  272|  2.31M|            } else if (next.kind == Token::FOR) {
  ------------------
  |  Branch (272:24): [True: 47.6k, False: 2.26M]
  ------------------
  273|       |                // It's a comprehension
  274|  47.6k|                unsigned num_fields = 0;
  275|  47.6k|                unsigned num_asserts = 0;
  276|  47.6k|                const ObjectField *field_ptr = nullptr;
  277|  47.7k|                for (const auto &field : fields) {
  ------------------
  |  Branch (277:40): [True: 47.7k, False: 47.6k]
  ------------------
  278|  47.7k|                    if (field.kind == ObjectField::LOCAL)
  ------------------
  |  Branch (278:25): [True: 1, False: 47.7k]
  ------------------
  279|      1|                        continue;
  280|  47.7k|                    if (field.kind == ObjectField::ASSERT) {
  ------------------
  |  Branch (280:25): [True: 75, False: 47.6k]
  ------------------
  281|     75|                        num_asserts++;
  282|     75|                        continue;
  283|     75|                    }
  284|  47.6k|                    field_ptr = &field;
  285|  47.6k|                    num_fields++;
  286|  47.6k|                }
  287|  47.6k|                if (num_asserts > 0) {
  ------------------
  |  Branch (287:21): [True: 10, False: 47.6k]
  ------------------
  288|     10|                    auto msg = "object comprehension cannot have asserts.";
  289|     10|                    throw StaticError(next.location, msg);
  290|     10|                }
  291|  47.6k|                if (num_fields != 1) {
  ------------------
  |  Branch (291:21): [True: 2, False: 47.6k]
  ------------------
  292|      2|                    auto msg = "object comprehension can only have one field.";
  293|      2|                    throw StaticError(next.location, msg);
  294|      2|                }
  295|  47.6k|                const ObjectField &field = *field_ptr;
  296|       |
  297|  47.6k|                if (field.hide != ObjectField::INHERIT) {
  ------------------
  |  Branch (297:21): [True: 3, False: 47.6k]
  ------------------
  298|      3|                    auto msg = "object comprehensions cannot have hidden fields.";
  299|      3|                    throw StaticError(next.location, msg);
  300|      3|                }
  301|       |
  302|  47.6k|                if (field.kind != ObjectField::FIELD_EXPR) {
  ------------------
  |  Branch (302:21): [True: 5, False: 47.6k]
  ------------------
  303|      5|                    auto msg = "object comprehensions can only have [e] fields.";
  304|      5|                    throw StaticError(next.location, msg);
  305|      5|                }
  306|       |
  307|  47.6k|                std::vector<ComprehensionSpec> specs;
  308|  47.6k|                Token last = parseComprehensionSpecs(Token::BRACE_R, next.fodder, specs);
  309|  47.6k|                obj = alloc->make<ObjectComprehension>(
  310|  47.6k|                    span(tok, last), tok.fodder, fields, got_comma, specs, last.fodder);
  311|       |
  312|  47.6k|                return last;
  313|  47.6k|            }
  314|       |
  315|  2.26M|            if (!got_comma && !first)
  ------------------
  |  Branch (315:17): [True: 481k, False: 1.78M]
  |  Branch (315:31): [True: 121, False: 481k]
  ------------------
  316|    121|                throw StaticError(next.location, "expected a comma before next field.");
  317|       |
  318|  2.26M|            first = false;
  319|  2.26M|            got_comma = false;
  320|       |
  321|  2.26M|            switch (next.kind) {
  322|  51.7k|                case Token::BRACKET_L:
  ------------------
  |  Branch (322:17): [True: 51.7k, False: 2.21M]
  ------------------
  323|  2.11M|                case Token::IDENTIFIER:
  ------------------
  |  Branch (323:17): [True: 2.05M, False: 206k]
  ------------------
  324|  2.13M|                case Token::STRING_DOUBLE:
  ------------------
  |  Branch (324:17): [True: 26.4k, False: 2.23M]
  ------------------
  325|  2.17M|                case Token::STRING_SINGLE:
  ------------------
  |  Branch (325:17): [True: 37.6k, False: 2.22M]
  ------------------
  326|  2.17M|                case Token::STRING_BLOCK:
  ------------------
  |  Branch (326:17): [True: 716, False: 2.26M]
  ------------------
  327|  2.17M|                case Token::VERBATIM_STRING_DOUBLE:
  ------------------
  |  Branch (327:17): [True: 540, False: 2.26M]
  ------------------
  328|  2.17M|                case Token::VERBATIM_STRING_SINGLE: {
  ------------------
  |  Branch (328:17): [True: 890, False: 2.26M]
  ------------------
  329|  2.17M|                    ObjectField::Kind kind;
  330|  2.17M|                    AST *expr1 = nullptr;
  331|  2.17M|                    const Identifier *id = nullptr;
  332|  2.17M|                    Fodder fodder1, fodder2;
  333|  2.17M|                    LocationRange idLocation;
  334|  2.17M|                    if (next.kind == Token::IDENTIFIER) {
  ------------------
  |  Branch (334:25): [True: 2.05M, False: 118k]
  ------------------
  335|  2.05M|                        fodder1 = next.fodder;
  336|  2.05M|                        kind = ObjectField::FIELD_ID;
  337|  2.05M|                        id = alloc->makeIdentifier(next.data32());
  338|  2.05M|                        idLocation = next.location;
  339|  2.05M|                    } else if (next.kind == Token::STRING_DOUBLE) {
  ------------------
  |  Branch (339:32): [True: 26.4k, False: 91.5k]
  ------------------
  340|  26.4k|                        kind = ObjectField::FIELD_STR;
  341|  26.4k|                        expr1 = alloc->make<LiteralString>(next.location,
  342|  26.4k|                                                           next.fodder,
  343|  26.4k|                                                           next.data32(),
  344|  26.4k|                                                           LiteralString::DOUBLE,
  345|  26.4k|                                                           "",
  346|  26.4k|                                                           "");
  347|  91.5k|                    } else if (next.kind == Token::STRING_SINGLE) {
  ------------------
  |  Branch (347:32): [True: 37.6k, False: 53.9k]
  ------------------
  348|  37.6k|                        kind = ObjectField::FIELD_STR;
  349|  37.6k|                        expr1 = alloc->make<LiteralString>(next.location,
  350|  37.6k|                                                           next.fodder,
  351|  37.6k|                                                           next.data32(),
  352|  37.6k|                                                           LiteralString::SINGLE,
  353|  37.6k|                                                           "",
  354|  37.6k|                                                           "");
  355|  53.9k|                    } else if (next.kind == Token::STRING_BLOCK) {
  ------------------
  |  Branch (355:32): [True: 716, False: 53.2k]
  ------------------
  356|    716|                        kind = ObjectField::FIELD_STR;
  357|    716|                        expr1 = alloc->make<LiteralString>(next.location,
  358|    716|                                                           next.fodder,
  359|    716|                                                           next.data32(),
  360|    716|                                                           LiteralString::BLOCK,
  361|    716|                                                           next.stringBlockIndent,
  362|    716|                                                           next.stringBlockTermIndent);
  363|  53.2k|                    } else if (next.kind == Token::VERBATIM_STRING_SINGLE) {
  ------------------
  |  Branch (363:32): [True: 890, False: 52.3k]
  ------------------
  364|    890|                        kind = ObjectField::FIELD_STR;
  365|    890|                        expr1 = alloc->make<LiteralString>(next.location,
  366|    890|                                                           next.fodder,
  367|    890|                                                           next.data32(),
  368|    890|                                                           LiteralString::VERBATIM_SINGLE,
  369|    890|                                                           "",
  370|    890|                                                           "");
  371|  52.3k|                    } else if (next.kind == Token::VERBATIM_STRING_DOUBLE) {
  ------------------
  |  Branch (371:32): [True: 540, False: 51.7k]
  ------------------
  372|    540|                        kind = ObjectField::FIELD_STR;
  373|    540|                        expr1 = alloc->make<LiteralString>(next.location,
  374|    540|                                                           next.fodder,
  375|    540|                                                           next.data32(),
  376|    540|                                                           LiteralString::VERBATIM_DOUBLE,
  377|    540|                                                           "",
  378|    540|                                                           "");
  379|  51.7k|                    } else {
  380|  51.7k|                        kind = ObjectField::FIELD_EXPR;
  381|  51.7k|                        fodder1 = next.fodder;
  382|  51.7k|                        expr1 = parse(MAX_PRECEDENCE);
  383|  51.7k|                        Token bracket_r = popExpect(Token::BRACKET_R);
  384|  51.7k|                        fodder2 = bracket_r.fodder;
  385|  51.7k|                    }
  386|       |
  387|  2.17M|                    bool is_method = false;
  388|  2.17M|                    bool meth_comma = false;
  389|  2.17M|                    ArgParams params;
  390|  2.17M|                    Fodder fodder_l;
  391|  2.17M|                    Fodder fodder_r;
  392|  2.17M|                    if (peek().kind == Token::PAREN_L) {
  ------------------
  |  Branch (392:25): [True: 1.11M, False: 1.05M]
  ------------------
  393|  1.11M|                        Token paren_l = pop();
  394|  1.11M|                        fodder_l = paren_l.fodder;
  395|  1.11M|                        params = parseParams("method parameter", meth_comma, fodder_r);
  396|  1.11M|                        is_method = true;
  397|  1.11M|                    }
  398|       |
  399|  2.17M|                    bool plus_sugar = false;
  400|       |
  401|  2.17M|                    Token op = popExpect(Token::OPERATOR);
  402|  2.17M|                    const char *od = op.data.c_str();
  403|  2.17M|                    if (*od == '+') {
  ------------------
  |  Branch (403:25): [True: 18.9k, False: 2.15M]
  ------------------
  404|  18.9k|                        plus_sugar = true;
  405|  18.9k|                        od++;
  406|  18.9k|                    }
  407|  2.17M|                    unsigned colons = 0;
  408|  5.46M|                    for (; *od != '\0'; ++od) {
  ------------------
  |  Branch (408:28): [True: 3.28M, False: 2.17M]
  ------------------
  409|  3.28M|                        if (*od != ':') {
  ------------------
  |  Branch (409:29): [True: 10, False: 3.28M]
  ------------------
  410|     10|                            throw StaticError(
  411|     10|                                next.location,
  412|     10|                                "expected one of :, ::, :::, +:, +::, +:::, got: " + op.data);
  413|     10|                        }
  414|  3.28M|                        ++colons;
  415|  3.28M|                    }
  416|  2.17M|                    ObjectField::Hide field_hide;
  417|  2.17M|                    switch (colons) {
  418|  1.05M|                        case 1: field_hide = ObjectField::INHERIT; break;
  ------------------
  |  Branch (418:25): [True: 1.05M, False: 1.11M]
  ------------------
  419|       |
  420|  1.11M|                        case 2: field_hide = ObjectField::HIDDEN; break;
  ------------------
  |  Branch (420:25): [True: 1.11M, False: 1.06M]
  ------------------
  421|       |
  422|    214|                        case 3: field_hide = ObjectField::VISIBLE; break;
  ------------------
  |  Branch (422:25): [True: 214, False: 2.17M]
  ------------------
  423|       |
  424|     12|                        default:
  ------------------
  |  Branch (424:25): [True: 12, False: 2.17M]
  ------------------
  425|     12|                            throw StaticError(
  426|     12|                                next.location,
  427|     12|                                "expected one of :, ::, :::, +:, +::, +:::, got: " + op.data);
  428|  2.17M|                    }
  429|       |
  430|       |                    // Basic checks for invalid Jsonnet code.
  431|  2.17M|                    if (is_method && plus_sugar) {
  ------------------
  |  Branch (431:25): [True: 1.11M, False: 1.05M]
  |  Branch (431:38): [True: 1, False: 1.11M]
  ------------------
  432|      1|                        throw StaticError(next.location,
  433|      1|                                          "cannot use +: syntax sugar in a method: " + next.data);
  434|      1|                    }
  435|  2.17M|                    if (kind != ObjectField::FIELD_EXPR) {
  ------------------
  |  Branch (435:25): [True: 2.12M, False: 51.5k]
  ------------------
  436|  2.12M|                        if (!literal_fields.insert(next.data).second) {
  ------------------
  |  Branch (436:29): [True: 6, False: 2.12M]
  ------------------
  437|      6|                            throw StaticError(next.location, "duplicate field: " + next.data);
  438|      6|                        }
  439|  2.12M|                    }
  440|       |
  441|  2.17M|                    AST *body = parse(MAX_PRECEDENCE);
  442|       |
  443|  2.17M|                    Fodder comma_fodder;
  444|  2.17M|                    next = pop();
  445|  2.17M|                    if (next.kind == Token::COMMA) {
  ------------------
  |  Branch (445:25): [True: 1.84M, False: 327k]
  ------------------
  446|  1.84M|                        comma_fodder = next.fodder;
  447|  1.84M|                        next = pop();
  448|  1.84M|                        got_comma = true;
  449|  1.84M|                    }
  450|  2.17M|                    fields.emplace_back(kind,
  451|  2.17M|                                        fodder1,
  452|  2.17M|                                        fodder2,
  453|  2.17M|                                        fodder_l,
  454|  2.17M|                                        fodder_r,
  455|  2.17M|                                        field_hide,
  456|  2.17M|                                        plus_sugar,
  457|  2.17M|                                        is_method,
  458|  2.17M|                                        expr1,
  459|  2.17M|                                        id,
  460|  2.17M|                                        idLocation,
  461|  2.17M|                                        params,
  462|  2.17M|                                        meth_comma,
  463|  2.17M|                                        op.fodder,
  464|  2.17M|                                        body,
  465|  2.17M|                                        nullptr,
  466|  2.17M|                                        comma_fodder);
  467|  2.17M|                } break;
  468|       |
  469|  65.6k|                case Token::LOCAL: {
  ------------------
  |  Branch (469:17): [True: 65.6k, False: 2.19M]
  ------------------
  470|  65.6k|                    Fodder local_fodder = next.fodder;
  471|  65.6k|                    Token var_id = popExpect(Token::IDENTIFIER);
  472|  65.6k|                    auto *id = alloc->makeIdentifier(var_id.data32());
  473|       |
  474|  65.6k|                    if (binds.find(id) != binds.end()) {
  ------------------
  |  Branch (474:25): [True: 3, False: 65.6k]
  ------------------
  475|      3|                        throw StaticError(var_id.location, "duplicate local var: " + var_id.data);
  476|      3|                    }
  477|  65.6k|                    bool is_method = false;
  478|  65.6k|                    bool func_comma = false;
  479|  65.6k|                    ArgParams params;
  480|  65.6k|                    Fodder paren_l_fodder;
  481|  65.6k|                    Fodder paren_r_fodder;
  482|  65.6k|                    if (peek().kind == Token::PAREN_L) {
  ------------------
  |  Branch (482:25): [True: 9.37k, False: 56.3k]
  ------------------
  483|  9.37k|                        Token paren_l = pop();
  484|  9.37k|                        paren_l_fodder = paren_l.fodder;
  485|  9.37k|                        is_method = true;
  486|  9.37k|                        params = parseParams("function parameter", func_comma, paren_r_fodder);
  487|  9.37k|                    }
  488|  65.6k|                    Token eq = popExpect(Token::OPERATOR, "=");
  489|  65.6k|                    AST *body = parse(MAX_PRECEDENCE);
  490|  65.6k|                    binds.insert(id);
  491|       |
  492|  65.6k|                    Fodder comma_fodder;
  493|  65.6k|                    next = pop();
  494|  65.6k|                    if (next.kind == Token::COMMA) {
  ------------------
  |  Branch (494:25): [True: 65.0k, False: 598]
  ------------------
  495|  65.0k|                        comma_fodder = next.fodder;
  496|  65.0k|                        next = pop();
  497|  65.0k|                        got_comma = true;
  498|  65.0k|                    }
  499|  65.6k|                    fields.push_back(ObjectField::Local(local_fodder,
  500|  65.6k|                                                        var_id.fodder,
  501|  65.6k|                                                        paren_l_fodder,
  502|  65.6k|                                                        paren_r_fodder,
  503|  65.6k|                                                        is_method,
  504|  65.6k|                                                        id,
  505|  65.6k|                                                        params,
  506|  65.6k|                                                        func_comma,
  507|  65.6k|                                                        eq.fodder,
  508|  65.6k|                                                        body,
  509|  65.6k|                                                        comma_fodder));
  510|       |
  511|  65.6k|                } break;
  512|       |
  513|  22.8k|                case Token::ASSERT: {
  ------------------
  |  Branch (513:17): [True: 22.8k, False: 2.24M]
  ------------------
  514|  22.8k|                    Fodder assert_fodder = next.fodder;
  515|  22.8k|                    AST *cond = parse(MAX_PRECEDENCE);
  516|  22.8k|                    AST *msg = nullptr;
  517|  22.8k|                    Fodder colon_fodder;
  518|  22.8k|                    if (peek().kind == Token::OPERATOR && peek().data == ":") {
  ------------------
  |  Branch (518:25): [True: 20.9k, False: 1.82k]
  |  Branch (518:59): [True: 20.9k, False: 1]
  ------------------
  519|  20.9k|                        Token colon = pop();
  520|  20.9k|                        colon_fodder = colon.fodder;
  521|  20.9k|                        msg = parse(MAX_PRECEDENCE);
  522|  20.9k|                    }
  523|       |
  524|  22.8k|                    Fodder comma_fodder;
  525|  22.8k|                    next = pop();
  526|  22.8k|                    if (next.kind == Token::COMMA) {
  ------------------
  |  Branch (526:25): [True: 20.5k, False: 2.23k]
  ------------------
  527|  20.5k|                        comma_fodder = next.fodder;
  528|  20.5k|                        next = pop();
  529|  20.5k|                        got_comma = true;
  530|  20.5k|                    }
  531|  22.8k|                    fields.push_back(
  532|  22.8k|                        ObjectField::Assert(assert_fodder, cond, colon_fodder, msg, comma_fodder));
  533|  22.8k|                } break;
  534|       |
  535|     94|                default: throw unexpected(next, "parsing field definition");
  ------------------
  |  Branch (535:17): [True: 94, False: 2.26M]
  ------------------
  536|  2.26M|            }
  537|       |
  538|  2.26M|        } while (true);
  ------------------
  |  Branch (538:18): [Folded - Ignored]
  ------------------
  539|   533k|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14spanERKNS0_5TokenES4_:
   79|  17.9M|{
   80|  17.9M|    return LocationRange(begin.location.file, begin.location.begin, end.location.end);
   81|  17.9M|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser23parseComprehensionSpecsENS0_5Token4KindENSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS6_INS0_17ComprehensionSpecENS8_ISB_EEEE:
  544|   355k|    {
  545|   394k|        while (true) {
  ------------------
  |  Branch (545:16): [Folded - Ignored]
  ------------------
  546|   393k|            LocationRange l;
  547|   393k|            Token id_token = popExpect(Token::IDENTIFIER);
  548|   393k|            const Identifier *id = alloc->makeIdentifier(id_token.data32());
  549|   393k|            Token in_token = popExpect(Token::IN);
  550|   393k|            AST *arr = parse(MAX_PRECEDENCE);
  551|   393k|            specs.emplace_back(
  552|   393k|                ComprehensionSpec::FOR, for_fodder, id_token.fodder, id, in_token.fodder, arr);
  553|       |
  554|   393k|            Token maybe_if = pop();
  555|   842k|            for (; maybe_if.kind == Token::IF; maybe_if = pop()) {
  ------------------
  |  Branch (555:20): [True: 448k, False: 393k]
  ------------------
  556|   448k|                AST *cond = parse(MAX_PRECEDENCE);
  557|   448k|                specs.emplace_back(
  558|   448k|                    ComprehensionSpec::IF, maybe_if.fodder, Fodder{}, nullptr, Fodder{}, cond);
  559|   448k|            }
  560|   393k|            if (maybe_if.kind == end) {
  ------------------
  |  Branch (560:17): [True: 354k, False: 39.1k]
  ------------------
  561|   354k|                return maybe_if;
  562|   354k|            }
  563|  39.1k|            if (maybe_if.kind != Token::FOR) {
  ------------------
  |  Branch (563:17): [True: 63, False: 39.0k]
  ------------------
  564|     63|                std::stringstream ss;
  565|     63|                ss << "expected for, if or " << end << " after for clause, got: " << maybe_if;
  566|     63|                throw StaticError(maybe_if.location, ss.str());
  567|     63|            }
  568|  39.0k|            for_fodder = maybe_if.fodder;
  569|  39.0k|        }
  570|   355k|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14spanERKNS0_5TokenE:
   74|  41.5M|{
   75|  41.5M|    return LocationRange(begin.location.file, begin.location.begin, begin.location.end);
   76|  41.5M|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser10parseInfixEPNS0_3ASTERKNS0_5TokenEj:
  926|  44.6M|    {
  927|  68.4M|        while (true) {
  ------------------
  |  Branch (927:16): [Folded - Ignored]
  ------------------
  928|       |
  929|  68.4M|            BinaryOp bop = BOP_PLUS;
  930|  68.4M|            unsigned op_precedence = 0;
  931|       |
  932|  68.4M|            switch (peek().kind) {
  933|       |                // Logical / arithmetic binary operator.
  934|  6.94k|                case Token::IN:
  ------------------
  |  Branch (934:17): [True: 6.94k, False: 68.4M]
  ------------------
  935|  10.6M|                case Token::OPERATOR:
  ------------------
  |  Branch (935:17): [True: 10.6M, False: 57.7M]
  ------------------
  936|       |                    // These occur if the outer statement was an assert or array slice.
  937|       |                    // Either way, we terminate the parsing here.
  938|  10.6M|                    if (peek().data == ":" || peek().data == "::") {
  ------------------
  |  Branch (938:25): [True: 766k, False: 9.89M]
  |  Branch (938:47): [True: 718, False: 9.89M]
  ------------------
  939|   767k|                        return lhs;
  940|   767k|                    }
  941|  9.89M|                    if (!op_is_binary(peek().data, bop)) {
  ------------------
  |  Branch (941:25): [True: 137, False: 9.89M]
  ------------------
  942|    137|                        std::stringstream ss;
  943|    137|                        ss << "not a binary operator: " << peek().data;
  944|    137|                        throw StaticError(peek().location, ss.str());
  945|    137|                    }
  946|  9.89M|                    op_precedence = precedence_map[bop];
  947|  9.89M|                    break;
  948|       |
  949|       |                // Index, Apply
  950|  6.57M|                case Token::DOT:
  ------------------
  |  Branch (950:17): [True: 6.57M, False: 61.8M]
  ------------------
  951|  8.17M|                case Token::BRACKET_L:
  ------------------
  |  Branch (951:17): [True: 1.60M, False: 66.8M]
  ------------------
  952|  15.6M|                case Token::PAREN_L:
  ------------------
  |  Branch (952:17): [True: 7.48M, False: 60.9M]
  ------------------
  953|  15.7M|                case Token::BRACE_L:
  ------------------
  |  Branch (953:17): [True: 85.6k, False: 68.3M]
  ------------------
  954|  15.7M|                    op_precedence = APPLY_PRECEDENCE;
  955|  15.7M|                    break;
  956|       |
  957|  42.0M|                default:
  ------------------
  |  Branch (957:17): [True: 42.0M, False: 26.4M]
  ------------------
  958|       |                    // This happens when we reach EOF or the terminating token of an outer context.
  959|  42.0M|                    return lhs;
  960|  68.4M|            }
  961|       |
  962|       |            // If higher precedence than the outer recursive call, let that handle it.
  963|  25.6M|            if (op_precedence >= max_precedence)
  ------------------
  |  Branch (963:17): [True: 1.87M, False: 23.7M]
  ------------------
  964|  1.87M|                return lhs;
  965|       |
  966|  23.7M|            Token op = pop();
  967|       |
  968|  23.7M|            switch (op.kind) {
  969|  1.60M|                case Token::BRACKET_L: {
  ------------------
  |  Branch (969:17): [True: 1.60M, False: 22.1M]
  ------------------
  970|  1.60M|                    bool is_slice;
  971|  1.60M|                    AST *first = nullptr;
  972|  1.60M|                    Fodder second_fodder;
  973|  1.60M|                    AST *second = nullptr;
  974|  1.60M|                    Fodder third_fodder;
  975|  1.60M|                    AST *third = nullptr;
  976|       |
  977|  1.60M|                    if (peek().kind == Token::BRACKET_R)
  ------------------
  |  Branch (977:25): [True: 4, False: 1.60M]
  ------------------
  978|      4|                        throw unexpected(pop(), "parsing index");
  979|       |
  980|  1.60M|                    if (peek().data != ":" && peek().data != "::") {
  ------------------
  |  Branch (980:25): [True: 1.57M, False: 23.1k]
  |  Branch (980:47): [True: 1.57M, False: 348]
  ------------------
  981|  1.57M|                        first = parse(MAX_PRECEDENCE);
  982|  1.57M|                    }
  983|       |
  984|  1.60M|                    if (peek().kind == Token::OPERATOR && peek().data == "::") {
  ------------------
  |  Branch (984:25): [True: 172k, False: 1.42M]
  |  Branch (984:59): [True: 607, False: 172k]
  ------------------
  985|       |                        // Handle ::
  986|    607|                        is_slice = true;
  987|    607|                        Token joined = pop();
  988|    607|                        second_fodder = joined.fodder;
  989|       |
  990|    607|                        if (peek().kind != Token::BRACKET_R)
  ------------------
  |  Branch (990:29): [True: 247, False: 360]
  ------------------
  991|    247|                            third = parse(MAX_PRECEDENCE);
  992|       |
  993|  1.60M|                    } else if (peek().kind != Token::BRACKET_R) {
  ------------------
  |  Branch (993:32): [True: 172k, False: 1.42M]
  ------------------
  994|   172k|                        is_slice = true;
  995|   172k|                        Token delim = pop();
  996|   172k|                        if (delim.data != ":")
  ------------------
  |  Branch (996:29): [True: 158, False: 172k]
  ------------------
  997|    158|                            throw unexpected(delim, "parsing slice");
  998|       |
  999|   172k|                        second_fodder = delim.fodder;
 1000|       |
 1001|   172k|                        if (peek().data != ":" && peek().kind != Token::BRACKET_R)
  ------------------
  |  Branch (1001:29): [True: 171k, False: 497]
  |  Branch (1001:51): [True: 76.6k, False: 95.0k]
  ------------------
 1002|  76.6k|                            second = parse(MAX_PRECEDENCE);
 1003|       |
 1004|   172k|                        if (peek().kind != Token::BRACKET_R) {
  ------------------
  |  Branch (1004:29): [True: 10.8k, False: 161k]
  ------------------
 1005|  10.8k|                            Token delim = pop();
 1006|  10.8k|                            if (delim.data != ":")
  ------------------
  |  Branch (1006:33): [True: 52, False: 10.7k]
  ------------------
 1007|     52|                                throw unexpected(delim, "parsing slice");
 1008|       |
 1009|  10.7k|                            third_fodder = delim.fodder;
 1010|       |
 1011|  10.7k|                            if (peek().kind != Token::BRACKET_R)
  ------------------
  |  Branch (1011:33): [True: 10.2k, False: 521]
  ------------------
 1012|  10.2k|                                third = parse(MAX_PRECEDENCE);
 1013|  10.7k|                        }
 1014|  1.42M|                    } else {
 1015|  1.42M|                        is_slice = false;
 1016|  1.42M|                    }
 1017|  1.60M|                    Token end = popExpect(Token::BRACKET_R);
 1018|  1.60M|                    lhs = alloc->make<Index>(span(begin, end),
 1019|  1.60M|                                             EMPTY_FODDER,
 1020|  1.60M|                                             lhs,
 1021|  1.60M|                                             op.fodder,
 1022|  1.60M|                                             is_slice,
 1023|  1.60M|                                             first,
 1024|  1.60M|                                             second_fodder,
 1025|  1.60M|                                             second,
 1026|  1.60M|                                             third_fodder,
 1027|  1.60M|                                             third,
 1028|  1.60M|                                             end.fodder);
 1029|  1.60M|                    break;
 1030|  1.60M|                }
 1031|  6.57M|                case Token::DOT: {
  ------------------
  |  Branch (1031:17): [True: 6.57M, False: 17.1M]
  ------------------
 1032|  6.57M|                    Token field_id = popExpect(Token::IDENTIFIER);
 1033|  6.57M|                    const Identifier *id = alloc->makeIdentifier(field_id.data32());
 1034|  6.57M|                    lhs = alloc->make<Index>(span(begin, field_id),
 1035|  6.57M|                                             EMPTY_FODDER,
 1036|  6.57M|                                             lhs,
 1037|  6.57M|                                             op.fodder,
 1038|  6.57M|                                             field_id.fodder,
 1039|  6.57M|                                             id);
 1040|  6.57M|                    break;
 1041|  1.60M|                }
 1042|  7.48M|                case Token::PAREN_L: {
  ------------------
  |  Branch (1042:17): [True: 7.48M, False: 16.2M]
  ------------------
 1043|  7.48M|                    ArgParams args;
 1044|  7.48M|                    bool got_comma;
 1045|  7.48M|                    Token end = parseArgs(args, "function argument", got_comma);
 1046|  7.48M|                    bool got_named = false;
 1047|  12.4M|                    for (const auto& arg : args) {
  ------------------
  |  Branch (1047:42): [True: 12.4M, False: 7.48M]
  ------------------
 1048|  12.4M|                        if (arg.id != nullptr) {
  ------------------
  |  Branch (1048:29): [True: 28.1k, False: 12.4M]
  ------------------
 1049|  28.1k|                            got_named = true;
 1050|  12.4M|                        } else {
 1051|  12.4M|                            if (got_named) {
  ------------------
  |  Branch (1051:33): [True: 3, False: 12.4M]
  ------------------
 1052|      3|                                throw StaticError(arg.expr->location, "Positional argument after a named argument is not allowed");
 1053|      3|                            }
 1054|  12.4M|                        }
 1055|  12.4M|                    }
 1056|  7.48M|                    bool tailstrict = false;
 1057|  7.48M|                    Fodder tailstrict_fodder;
 1058|  7.48M|                    if (peek().kind == Token::TAILSTRICT) {
  ------------------
  |  Branch (1058:25): [True: 371k, False: 7.11M]
  ------------------
 1059|   371k|                        Token tailstrict_token = pop();
 1060|   371k|                        tailstrict_fodder = tailstrict_token.fodder;
 1061|   371k|                        tailstrict = true;
 1062|   371k|                    }
 1063|  7.48M|                    lhs = alloc->make<Apply>(span(begin, end),
 1064|  7.48M|                                             EMPTY_FODDER,
 1065|  7.48M|                                             lhs,
 1066|  7.48M|                                             op.fodder,
 1067|  7.48M|                                             args,
 1068|  7.48M|                                             got_comma,
 1069|  7.48M|                                             end.fodder,
 1070|  7.48M|                                             tailstrict_fodder,
 1071|  7.48M|                                             tailstrict);
 1072|  7.48M|                    break;
 1073|  7.48M|                }
 1074|  85.6k|                case Token::BRACE_L: {
  ------------------
  |  Branch (1074:17): [True: 85.6k, False: 23.6M]
  ------------------
 1075|  85.6k|                    AST *obj;
 1076|  85.6k|                    Token end = parseObjectRemainder(obj, op);
 1077|  85.6k|                    lhs = alloc->make<ApplyBrace>(span(begin, end), EMPTY_FODDER, lhs, obj);
 1078|  85.6k|                    break;
 1079|  7.48M|                }
 1080|       |
 1081|  5.15k|                case Token::IN: {
  ------------------
  |  Branch (1081:17): [True: 5.15k, False: 23.7M]
  ------------------
 1082|  5.15k|                    if (peek().kind == Token::SUPER) {
  ------------------
  |  Branch (1082:25): [True: 420, False: 4.73k]
  ------------------
 1083|    420|                        Token super = pop();
 1084|    420|                        lhs = alloc->make<InSuper>(
 1085|    420|                            span(begin, super), EMPTY_FODDER, lhs, op.fodder, super.fodder);
 1086|  4.73k|                    } else {
 1087|  4.73k|                        AST *rhs = parse(op_precedence);
 1088|  4.73k|                        lhs = alloc->make<Binary>(
 1089|  4.73k|                            span(begin, rhs), EMPTY_FODDER, lhs, op.fodder, bop, rhs);
 1090|  4.73k|                    }
 1091|  5.15k|                    break;
 1092|  7.48M|                }
 1093|       |
 1094|  8.02M|                case Token::OPERATOR: {
  ------------------
  |  Branch (1094:17): [True: 8.02M, False: 15.7M]
  ------------------
 1095|  8.02M|                    AST *rhs = parse(op_precedence);
 1096|  8.02M|                    lhs = alloc->make<Binary>(
 1097|  8.02M|                        span(begin, rhs), EMPTY_FODDER, lhs, op.fodder, bop, rhs);
 1098|  8.02M|                    break;
 1099|  7.48M|                }
 1100|       |
 1101|      0|                default: {
  ------------------
  |  Branch (1101:17): [True: 0, False: 23.7M]
  ------------------
 1102|      0|                    std::cerr << "Should not be here." << std::endl;
 1103|      0|                    abort();
 1104|  7.48M|                }
 1105|  23.7M|            }
 1106|  23.7M|        }
 1107|       |
 1108|       |        // (1 & ((1 + (1 * 1)) + 1)) & 1
 1109|       |        //
 1110|       |        //
 1111|       |
 1112|       |/*
 1113|       |        // Allocate this on the heap to control stack growth.
 1114|       |        std::unique_ptr<Token> begin_(new Token(peek()));
 1115|       |        const Token &begin = *begin_;
 1116|       |*/
 1117|  44.6M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_112op_is_binaryERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERNS0_8BinaryOpE:
   65|  9.89M|{
   66|  9.89M|    auto it = binary_map.find(op);
   67|  9.89M|    if (it == binary_map.end())
  ------------------
  |  Branch (67:9): [True: 137, False: 9.89M]
  ------------------
   68|    137|        return false;
   69|  9.89M|    bop = it->second;
   70|  9.89M|    return true;
   71|  9.89M|}

_ZN7jsonnet8internal12CompilerPass6fodderERNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEE:
   22|  35.0M|{
   23|  35.0M|    for (auto &f : fodder)
  ------------------
  |  Branch (23:18): [True: 62.1k, False: 35.0M]
  ------------------
   24|  62.1k|        fodderElement(f);
   25|  35.0M|}
_ZN7jsonnet8internal12CompilerPass6paramsERNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEERNS3_INS0_8ArgParamENS5_IS9_EEEES8_:
   43|   754k|{
   44|   754k|    fodder(fodder_l);
   45|  1.44M|    for (auto &param : params) {
  ------------------
  |  Branch (45:22): [True: 1.44M, False: 754k]
  ------------------
   46|  1.44M|        fodder(param.idFodder);
   47|  1.44M|        if (param.expr) {
  ------------------
  |  Branch (47:13): [True: 1.37M, False: 68.6k]
  ------------------
   48|  1.37M|            fodder(param.eqFodder);
   49|  1.37M|            expr(param.expr);
   50|  1.37M|        }
   51|  1.44M|        fodder(param.commaFodder);
   52|  1.44M|    }
   53|   754k|    fodder(fodder_r);
   54|   754k|}
_ZN7jsonnet8internal12CompilerPass4exprERPNS0_3ASTE:
  110|  21.5M|{
  111|  21.5M|    fodder(ast_->openFodder);
  112|  21.5M|    visitExpr(ast_);
  113|  21.5M|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5ApplyE:
  116|   719k|{
  117|   719k|    expr(ast->target);
  118|   719k|    params(ast->fodderL, ast->args, ast->fodderR);
  119|   719k|    if (ast->tailstrict) {
  ------------------
  |  Branch (119:9): [True: 210k, False: 508k]
  ------------------
  120|   210k|        fodder(ast->tailstrictFodder);
  121|   210k|    }
  122|   719k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5ArrayE:
  131|   184k|{
  132|   248k|    for (auto &element : ast->elements) {
  ------------------
  |  Branch (132:24): [True: 248k, False: 184k]
  ------------------
  133|   248k|        expr(element.expr);
  134|   248k|        fodder(element.commaFodder);
  135|   248k|    }
  136|   184k|    fodder(ast->closeFodder);
  137|   184k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_6BinaryE:
  159|  1.45M|{
  160|  1.45M|    expr(ast->left);
  161|  1.45M|    fodder(ast->opFodder);
  162|  1.45M|    expr(ast->right);
  163|  1.45M|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_11ConditionalE:
  166|   476k|{
  167|   476k|    expr(ast->cond);
  168|   476k|    fodder(ast->thenFodder);
  169|   476k|    if (ast->branchFalse != nullptr) {
  ------------------
  |  Branch (169:9): [True: 476k, False: 0]
  ------------------
  170|   476k|        expr(ast->branchTrue);
  171|   476k|        fodder(ast->elseFodder);
  172|   476k|        expr(ast->branchFalse);
  173|   476k|    } else {
  174|      0|        expr(ast->branchTrue);
  175|      0|    }
  176|   476k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5ErrorE:
  179|  57.9k|{
  180|  57.9k|    expr(ast->expr);
  181|  57.9k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_8FunctionE:
  184|  35.6k|{
  185|  35.6k|    params(ast->parenLeftFodder, ast->params, ast->parenRightFodder);
  186|  35.6k|    expr(ast->body);
  187|  35.6k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_6ImportE:
  190|    363|{
  191|    363|    visit(ast->file);
  192|    363|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_9ImportstrE:
  195|  16.9k|{
  196|  16.9k|    visit(ast->file);
  197|  16.9k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_9ImportbinE:
  200|     68|{
  201|     68|    visit(ast->file);
  202|     68|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_7InSuperE:
  205|   170k|{
  206|   170k|    expr(ast->element);
  207|   170k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5IndexE:
  210|   813k|{
  211|   813k|    expr(ast->target);
  212|   813k|    if (ast->id != nullptr) {
  ------------------
  |  Branch (212:9): [True: 0, False: 813k]
  ------------------
  213|   813k|    } else {
  214|   813k|        if (ast->isSlice) {
  ------------------
  |  Branch (214:13): [True: 0, False: 813k]
  ------------------
  215|      0|            if (ast->index != nullptr)
  ------------------
  |  Branch (215:17): [True: 0, False: 0]
  ------------------
  216|      0|                expr(ast->index);
  217|      0|            if (ast->end != nullptr)
  ------------------
  |  Branch (217:17): [True: 0, False: 0]
  ------------------
  218|      0|                expr(ast->end);
  219|      0|            if (ast->step != nullptr)
  ------------------
  |  Branch (219:17): [True: 0, False: 0]
  ------------------
  220|      0|                expr(ast->step);
  221|   813k|        } else {
  222|   813k|            expr(ast->index);
  223|   813k|        }
  224|   813k|    }
  225|   813k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5LocalE:
  228|   327k|{
  229|   327k|    assert(ast->binds.size() > 0);
  230|  1.56M|    for (auto &bind : ast->binds) {
  ------------------
  |  Branch (230:21): [True: 1.56M, False: 327k]
  ------------------
  231|  1.56M|        fodder(bind.varFodder);
  232|  1.56M|        if (bind.functionSugar) {
  ------------------
  |  Branch (232:13): [True: 0, False: 1.56M]
  ------------------
  233|      0|            params(bind.parenLeftFodder, bind.params, bind.parenRightFodder);
  234|      0|        }
  235|  1.56M|        fodder(bind.opFodder);
  236|  1.56M|        expr(bind.body);
  237|  1.56M|        fodder(bind.closeFodder);
  238|  1.56M|    }
  239|   327k|    expr(ast->body);
  240|   327k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_15DesugaredObjectE:
  249|   821k|{
  250|   821k|    for (AST *assert : ast->asserts) {
  ------------------
  |  Branch (250:22): [True: 21.9k, False: 821k]
  ------------------
  251|  21.9k|        expr(assert);
  252|  21.9k|    }
  253|   821k|    for (auto &field : ast->fields) {
  ------------------
  |  Branch (253:22): [True: 474k, False: 821k]
  ------------------
  254|   474k|        expr(field.name);
  255|   474k|        expr(field.body);
  256|   474k|    }
  257|   821k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_25ObjectComprehensionSimpleE:
  267|  30.3k|{
  268|  30.3k|    expr(ast->field);
  269|  30.3k|    expr(ast->value);
  270|  30.3k|    expr(ast->array);
  271|  30.3k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_10SuperIndexE:
  280|   200k|{
  281|   200k|    if (ast->id != nullptr) {
  ------------------
  |  Branch (281:9): [True: 0, False: 200k]
  ------------------
  282|   200k|    } else {
  283|   200k|        expr(ast->index);
  284|   200k|    }
  285|   200k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5UnaryE:
  288|  9.71M|{
  289|  9.71M|    expr(ast->expr);
  290|  9.71M|}
_ZN7jsonnet8internal12CompilerPass9visitExprERPNS0_3ASTE:
  300|  21.5M|{
  301|  21.5M|    switch(ast_->type) {
  302|   719k|        VISIT(ast_, AST_APPLY, Apply);
  ------------------
  |  |  293|   719k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 719k, False: 20.7M]
  |  |  ------------------
  |  |  294|   719k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   719k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   719k|     visit(ast); \
  |  |  297|   719k|   } break
  ------------------
  303|      0|        VISIT(ast_, AST_APPLY_BRACE, ApplyBrace);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 21.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  304|   184k|        VISIT(ast_, AST_ARRAY, Array);
  ------------------
  |  |  293|   184k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 184k, False: 21.3M]
  |  |  ------------------
  |  |  294|   184k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   184k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   184k|     visit(ast); \
  |  |  297|   184k|   } break
  ------------------
  305|      0|        VISIT(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehension);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 21.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  306|       |        // VISIT(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehensionSimple);
  307|      0|        VISIT(ast_, AST_ASSERT, Assert);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 21.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  308|  1.45M|        VISIT(ast_, AST_BINARY, Binary);
  ------------------
  |  |  293|  1.45M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 1.45M, False: 20.0M]
  |  |  ------------------
  |  |  294|  1.45M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  1.45M|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  1.45M|     visit(ast); \
  |  |  297|  1.45M|   } break
  ------------------
  309|      0|        VISIT(ast_, AST_BUILTIN_FUNCTION, BuiltinFunction);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 21.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  310|   476k|        VISIT(ast_, AST_CONDITIONAL, Conditional);
  ------------------
  |  |  293|   476k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 476k, False: 21.0M]
  |  |  ------------------
  |  |  294|   476k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   476k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   476k|     visit(ast); \
  |  |  297|   476k|   } break
  ------------------
  311|   821k|        VISIT(ast_, AST_DESUGARED_OBJECT, DesugaredObject);
  ------------------
  |  |  293|   821k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 821k, False: 20.6M]
  |  |  ------------------
  |  |  294|   821k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   821k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   821k|     visit(ast); \
  |  |  297|   821k|   } break
  ------------------
  312|      0|        VISIT(ast_, AST_DOLLAR, Dollar);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 21.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  313|  57.9k|        VISIT(ast_, AST_ERROR, Error);
  ------------------
  |  |  293|  57.9k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 57.9k, False: 21.4M]
  |  |  ------------------
  |  |  294|  57.9k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  57.9k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  57.9k|     visit(ast); \
  |  |  297|  57.9k|   } break
  ------------------
  314|  35.6k|        VISIT(ast_, AST_FUNCTION, Function);
  ------------------
  |  |  293|  35.6k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 35.6k, False: 21.4M]
  |  |  ------------------
  |  |  294|  35.6k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  35.6k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  35.6k|     visit(ast); \
  |  |  297|  35.6k|   } break
  ------------------
  315|    363|        VISIT(ast_, AST_IMPORT, Import);
  ------------------
  |  |  293|    363|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 363, False: 21.5M]
  |  |  ------------------
  |  |  294|    363|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|    363|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|    363|     visit(ast); \
  |  |  297|    363|   } break
  ------------------
  316|  16.9k|        VISIT(ast_, AST_IMPORTSTR, Importstr);
  ------------------
  |  |  293|  16.9k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 16.9k, False: 21.4M]
  |  |  ------------------
  |  |  294|  16.9k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  16.9k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  16.9k|     visit(ast); \
  |  |  297|  16.9k|   } break
  ------------------
  317|     68|        VISIT(ast_, AST_IMPORTBIN, Importbin);
  ------------------
  |  |  293|     68|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 68, False: 21.5M]
  |  |  ------------------
  |  |  294|     68|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|     68|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|     68|     visit(ast); \
  |  |  297|     68|   } break
  ------------------
  318|   813k|        VISIT(ast_, AST_INDEX, Index);
  ------------------
  |  |  293|   813k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 813k, False: 20.6M]
  |  |  ------------------
  |  |  294|   813k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   813k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   813k|     visit(ast); \
  |  |  297|   813k|   } break
  ------------------
  319|   170k|        VISIT(ast_, AST_IN_SUPER, InSuper);
  ------------------
  |  |  293|   170k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 170k, False: 21.3M]
  |  |  ------------------
  |  |  294|   170k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   170k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   170k|     visit(ast); \
  |  |  297|   170k|   } break
  ------------------
  320|  38.6k|        VISIT(ast_, AST_LITERAL_BOOLEAN, LiteralBoolean);
  ------------------
  |  |  293|  38.6k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 38.6k, False: 21.4M]
  |  |  ------------------
  |  |  294|  38.6k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  38.6k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  38.6k|     visit(ast); \
  |  |  297|  38.6k|   } break
  ------------------
  321|  52.9k|        VISIT(ast_, AST_LITERAL_NULL, LiteralNull);
  ------------------
  |  |  293|  52.9k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 52.9k, False: 21.4M]
  |  |  ------------------
  |  |  294|  52.9k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  52.9k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  52.9k|     visit(ast); \
  |  |  297|  52.9k|   } break
  ------------------
  322|  1.12M|        VISIT(ast_, AST_LITERAL_NUMBER, LiteralNumber);
  ------------------
  |  |  293|  1.12M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 1.12M, False: 20.3M]
  |  |  ------------------
  |  |  294|  1.12M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  1.12M|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  1.12M|     visit(ast); \
  |  |  297|  1.12M|   } break
  ------------------
  323|  1.79M|        VISIT(ast_, AST_LITERAL_STRING, LiteralString);
  ------------------
  |  |  293|  1.79M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 1.79M, False: 19.7M]
  |  |  ------------------
  |  |  294|  1.79M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  1.79M|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  1.79M|     visit(ast); \
  |  |  297|  1.79M|   } break
  ------------------
  324|   327k|        VISIT(ast_, AST_LOCAL, Local);
  ------------------
  |  |  293|   327k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 327k, False: 21.1M]
  |  |  ------------------
  |  |  294|   327k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   327k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   327k|     visit(ast); \
  |  |  297|   327k|   } break
  ------------------
  325|      0|        VISIT(ast_, AST_OBJECT, Object);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 21.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  326|      0|        VISIT(ast_, AST_OBJECT_COMPREHENSION, ObjectComprehension);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 21.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  327|  30.3k|        VISIT(ast_, AST_OBJECT_COMPREHENSION_SIMPLE, ObjectComprehensionSimple);
  ------------------
  |  |  293|  30.3k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 30.3k, False: 21.4M]
  |  |  ------------------
  |  |  294|  30.3k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  30.3k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  30.3k|     visit(ast); \
  |  |  297|  30.3k|   } break
  ------------------
  328|      0|        VISIT(ast_, AST_PARENS, Parens);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 21.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  329|  13.5k|        VISIT(ast_, AST_SELF, Self);
  ------------------
  |  |  293|  13.5k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 13.5k, False: 21.4M]
  |  |  ------------------
  |  |  294|  13.5k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  13.5k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  13.5k|     visit(ast); \
  |  |  297|  13.5k|   } break
  ------------------
  330|   200k|        VISIT(ast_, AST_SUPER_INDEX, SuperIndex);
  ------------------
  |  |  293|   200k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 200k, False: 21.3M]
  |  |  ------------------
  |  |  294|   200k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   200k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   200k|     visit(ast); \
  |  |  297|   200k|   } break
  ------------------
  331|  9.71M|        VISIT(ast_, AST_UNARY, Unary);
  ------------------
  |  |  293|  9.71M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 9.71M, False: 11.7M]
  |  |  ------------------
  |  |  294|  9.71M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  9.71M|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  9.71M|     visit(ast); \
  |  |  297|  9.71M|   } break
  ------------------
  332|  3.45M|        VISIT(ast_, AST_VAR, Var);
  ------------------
  |  |  293|  3.45M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 3.45M, False: 18.0M]
  |  |  ------------------
  |  |  294|  3.45M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  3.45M|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  3.45M|     visit(ast); \
  |  |  297|  3.45M|   } break
  ------------------
  333|      0|        default:
  ------------------
  |  Branch (333:9): [True: 0, False: 21.5M]
  ------------------
  334|      0|            std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
  335|      0|            std::abort();
  336|      0|            break;
  337|  21.5M|    }
  338|  21.5M|}
_ZN7jsonnet8internal9ClonePass4exprERPNS0_3ASTE:
  361|  18.7M|{
  362|  18.7M|    switch(ast_->type) {
  363|   631k|        CLONE(ast_, AST_APPLY, Apply);
  ------------------
  |  |  354|   631k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 631k, False: 18.1M]
  |  |  ------------------
  |  |  355|   631k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|   631k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|   631k|     var = alloc.clone(ast); \
  |  |  358|   631k|   } break
  ------------------
  364|      0|        CLONE(ast_, AST_APPLY_BRACE, ApplyBrace);
  ------------------
  |  |  354|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 0, False: 18.7M]
  |  |  ------------------
  |  |  355|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|      0|     var = alloc.clone(ast); \
  |  |  358|      0|   } break
  ------------------
  365|   172k|        CLONE(ast_, AST_ARRAY, Array);
  ------------------
  |  |  354|   172k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 172k, False: 18.6M]
  |  |  ------------------
  |  |  355|   172k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|   172k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|   172k|     var = alloc.clone(ast); \
  |  |  358|   172k|   } break
  ------------------
  366|      0|        CLONE(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehension);
  ------------------
  |  |  354|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 0, False: 18.7M]
  |  |  ------------------
  |  |  355|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|      0|     var = alloc.clone(ast); \
  |  |  358|      0|   } break
  ------------------
  367|       |        // CLONE(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehensionSimple);
  368|      0|        CLONE(ast_, AST_ASSERT, Assert);
  ------------------
  |  |  354|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 0, False: 18.7M]
  |  |  ------------------
  |  |  355|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|      0|     var = alloc.clone(ast); \
  |  |  358|      0|   } break
  ------------------
  369|  1.26M|        CLONE(ast_, AST_BINARY, Binary);
  ------------------
  |  |  354|  1.26M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 1.26M, False: 17.5M]
  |  |  ------------------
  |  |  355|  1.26M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  1.26M|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  1.26M|     var = alloc.clone(ast); \
  |  |  358|  1.26M|   } break
  ------------------
  370|      0|        CLONE(ast_, AST_BUILTIN_FUNCTION, BuiltinFunction);
  ------------------
  |  |  354|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 0, False: 18.7M]
  |  |  ------------------
  |  |  355|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|      0|     var = alloc.clone(ast); \
  |  |  358|      0|   } break
  ------------------
  371|   422k|        CLONE(ast_, AST_CONDITIONAL, Conditional);
  ------------------
  |  |  354|   422k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 422k, False: 18.3M]
  |  |  ------------------
  |  |  355|   422k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|   422k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|   422k|     var = alloc.clone(ast); \
  |  |  358|   422k|   } break
  ------------------
  372|   720k|        CLONE(ast_, AST_DESUGARED_OBJECT, DesugaredObject);
  ------------------
  |  |  354|   720k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 720k, False: 18.0M]
  |  |  ------------------
  |  |  355|   720k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|   720k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|   720k|     var = alloc.clone(ast); \
  |  |  358|   720k|   } break
  ------------------
  373|      0|        CLONE(ast_, AST_DOLLAR, Dollar);
  ------------------
  |  |  354|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 0, False: 18.7M]
  |  |  ------------------
  |  |  355|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|      0|     var = alloc.clone(ast); \
  |  |  358|      0|   } break
  ------------------
  374|  52.2k|        CLONE(ast_, AST_ERROR, Error);
  ------------------
  |  |  354|  52.2k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 52.2k, False: 18.7M]
  |  |  ------------------
  |  |  355|  52.2k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  52.2k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  52.2k|     var = alloc.clone(ast); \
  |  |  358|  52.2k|   } break
  ------------------
  375|  32.6k|        CLONE(ast_, AST_FUNCTION, Function);
  ------------------
  |  |  354|  32.6k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 32.6k, False: 18.7M]
  |  |  ------------------
  |  |  355|  32.6k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  32.6k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  32.6k|     var = alloc.clone(ast); \
  |  |  358|  32.6k|   } break
  ------------------
  376|    254|        CLONE(ast_, AST_IMPORT, Import);
  ------------------
  |  |  354|    254|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 254, False: 18.7M]
  |  |  ------------------
  |  |  355|    254|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|    254|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|    254|     var = alloc.clone(ast); \
  |  |  358|    254|   } break
  ------------------
  377|  12.3k|        CLONE(ast_, AST_IMPORTSTR, Importstr);
  ------------------
  |  |  354|  12.3k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 12.3k, False: 18.7M]
  |  |  ------------------
  |  |  355|  12.3k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  12.3k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  12.3k|     var = alloc.clone(ast); \
  |  |  358|  12.3k|   } break
  ------------------
  378|     68|        CLONE(ast_, AST_IMPORTBIN, Importbin);
  ------------------
  |  |  354|     68|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 68, False: 18.7M]
  |  |  ------------------
  |  |  355|     68|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|     68|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|     68|     var = alloc.clone(ast); \
  |  |  358|     68|   } break
  ------------------
  379|   716k|        CLONE(ast_, AST_INDEX, Index);
  ------------------
  |  |  354|   716k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 716k, False: 18.0M]
  |  |  ------------------
  |  |  355|   716k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|   716k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|   716k|     var = alloc.clone(ast); \
  |  |  358|   716k|   } break
  ------------------
  380|   170k|        CLONE(ast_, AST_IN_SUPER, InSuper);
  ------------------
  |  |  354|   170k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 170k, False: 18.6M]
  |  |  ------------------
  |  |  355|   170k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|   170k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|   170k|     var = alloc.clone(ast); \
  |  |  358|   170k|   } break
  ------------------
  381|  34.3k|        CLONE(ast_, AST_LITERAL_BOOLEAN, LiteralBoolean);
  ------------------
  |  |  354|  34.3k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 34.3k, False: 18.7M]
  |  |  ------------------
  |  |  355|  34.3k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  34.3k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  34.3k|     var = alloc.clone(ast); \
  |  |  358|  34.3k|   } break
  ------------------
  382|  52.7k|        CLONE(ast_, AST_LITERAL_NULL, LiteralNull);
  ------------------
  |  |  354|  52.7k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 52.7k, False: 18.7M]
  |  |  ------------------
  |  |  355|  52.7k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  52.7k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  52.7k|     var = alloc.clone(ast); \
  |  |  358|  52.7k|   } break
  ------------------
  383|   983k|        CLONE(ast_, AST_LITERAL_NUMBER, LiteralNumber);
  ------------------
  |  |  354|   983k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 983k, False: 17.8M]
  |  |  ------------------
  |  |  355|   983k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|   983k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|   983k|     var = alloc.clone(ast); \
  |  |  358|   983k|   } break
  ------------------
  384|  1.60M|        CLONE(ast_, AST_LITERAL_STRING, LiteralString);
  ------------------
  |  |  354|  1.60M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 1.60M, False: 17.1M]
  |  |  ------------------
  |  |  355|  1.60M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  1.60M|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  1.60M|     var = alloc.clone(ast); \
  |  |  358|  1.60M|   } break
  ------------------
  385|   313k|        CLONE(ast_, AST_LOCAL, Local);
  ------------------
  |  |  354|   313k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 313k, False: 18.4M]
  |  |  ------------------
  |  |  355|   313k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|   313k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|   313k|     var = alloc.clone(ast); \
  |  |  358|   313k|   } break
  ------------------
  386|      0|        CLONE(ast_, AST_OBJECT, Object);
  ------------------
  |  |  354|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 0, False: 18.7M]
  |  |  ------------------
  |  |  355|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|      0|     var = alloc.clone(ast); \
  |  |  358|      0|   } break
  ------------------
  387|      0|        CLONE(ast_, AST_OBJECT_COMPREHENSION, ObjectComprehension);
  ------------------
  |  |  354|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 0, False: 18.7M]
  |  |  ------------------
  |  |  355|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|      0|     var = alloc.clone(ast); \
  |  |  358|      0|   } break
  ------------------
  388|  27.4k|        CLONE(ast_, AST_OBJECT_COMPREHENSION_SIMPLE, ObjectComprehensionSimple);
  ------------------
  |  |  354|  27.4k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 27.4k, False: 18.7M]
  |  |  ------------------
  |  |  355|  27.4k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  27.4k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  27.4k|     var = alloc.clone(ast); \
  |  |  358|  27.4k|   } break
  ------------------
  389|      0|        CLONE(ast_, AST_PARENS, Parens);
  ------------------
  |  |  354|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 0, False: 18.7M]
  |  |  ------------------
  |  |  355|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|      0|     var = alloc.clone(ast); \
  |  |  358|      0|   } break
  ------------------
  390|  13.5k|        CLONE(ast_, AST_SELF, Self);
  ------------------
  |  |  354|  13.5k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 13.5k, False: 18.7M]
  |  |  ------------------
  |  |  355|  13.5k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  13.5k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  13.5k|     var = alloc.clone(ast); \
  |  |  358|  13.5k|   } break
  ------------------
  391|   200k|        CLONE(ast_, AST_SUPER_INDEX, SuperIndex);
  ------------------
  |  |  354|   200k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 200k, False: 18.5M]
  |  |  ------------------
  |  |  355|   200k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|   200k|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|   200k|     var = alloc.clone(ast); \
  |  |  358|   200k|   } break
  ------------------
  392|  8.36M|        CLONE(ast_, AST_UNARY, Unary);
  ------------------
  |  |  354|  8.36M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 8.36M, False: 10.4M]
  |  |  ------------------
  |  |  355|  8.36M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  8.36M|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  8.36M|     var = alloc.clone(ast); \
  |  |  358|  8.36M|   } break
  ------------------
  393|  3.00M|        CLONE(ast_, AST_VAR, Var);
  ------------------
  |  |  354|  3.00M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (354:4): [True: 3.00M, False: 15.7M]
  |  |  ------------------
  |  |  355|  3.00M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  356|  3.00M|     auto *ast = static_cast<astClass *>(var); \
  |  |  357|  3.00M|     var = alloc.clone(ast); \
  |  |  358|  3.00M|   } break
  ------------------
  394|      0|        default:
  ------------------
  |  Branch (394:9): [True: 0, False: 18.7M]
  ------------------
  395|      0|            std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
  396|      0|            std::abort();
  397|      0|            break;
  398|  18.7M|    }
  399|       |
  400|  18.7M|    CompilerPass::expr(ast_);
  401|  18.7M|}
_ZN7jsonnet8internal9clone_astERNS0_9AllocatorEPNS0_3ASTE:
  404|  49.7k|{
  405|  49.7k|    AST *r = ast;
  406|  49.7k|    ClonePass(alloc).expr(r);
  407|  49.7k|    return r;
  408|  49.7k|}
_ZN7jsonnet8internal9ClonePassC2ERNS0_9AllocatorE:
  349|  49.7k|    ClonePass(Allocator &alloc) : CompilerPass(alloc) {}

_ZN7jsonnet8internal12CompilerPassC2ERNS0_9AllocatorE:
   32|  66.3k|    CompilerPass(Allocator &alloc) : alloc(alloc) {}
_ZN7jsonnet8internal12CompilerPass13fodderElementERNS0_13FodderElementE:
   34|  62.1k|    virtual void fodderElement(FodderElement &) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_14LiteralBooleanE:
   82|  38.6k|    virtual void visit(LiteralBoolean *) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_13LiteralNumberE:
   84|  1.12M|    virtual void visit(LiteralNumber *) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_13LiteralStringE:
   86|  1.80M|    virtual void visit(LiteralString *) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_11LiteralNullE:
   88|  52.9k|    virtual void visit(LiteralNull *) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_4SelfE:
  100|  13.5k|    virtual void visit(Self *) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_3VarE:
  106|  3.45M|    virtual void visit(Var *) {}

vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14HeapC2Ejd:
  333|  4.16k|    {
  334|  4.16k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_18type_strENS1_5Value4TypeE:
   74|  1.87k|{
   75|  1.87k|    switch (t) {
   76|      6|        case Value::NULL_TYPE: return "null";
  ------------------
  |  Branch (76:9): [True: 6, False: 1.87k]
  ------------------
   77|    280|        case Value::BOOLEAN: return "boolean";
  ------------------
  |  Branch (77:9): [True: 280, False: 1.59k]
  ------------------
   78|    402|        case Value::NUMBER: return "number";
  ------------------
  |  Branch (78:9): [True: 402, False: 1.47k]
  ------------------
   79|     49|        case Value::ARRAY: return "array";
  ------------------
  |  Branch (79:9): [True: 49, False: 1.82k]
  ------------------
   80|      2|        case Value::FUNCTION: return "function";
  ------------------
  |  Branch (80:9): [True: 2, False: 1.87k]
  ------------------
   81|    348|        case Value::OBJECT: return "object";
  ------------------
  |  Branch (81:9): [True: 348, False: 1.52k]
  ------------------
   82|    790|        case Value::STRING: return "string";
  ------------------
  |  Branch (82:9): [True: 790, False: 1.08k]
  ------------------
   83|      0|        default:
  ------------------
  |  Branch (83:9): [True: 0, False: 1.87k]
  ------------------
   84|      0|            std::cerr << "INTERNAL ERROR: Unknown type: " << t << std::endl;
   85|      0|            std::abort();
   86|      0|            return "";  // Quiet, compiler.
   87|  1.87k|    }
   88|  1.87k|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_18type_strERKNS1_5ValueE:
   92|    399|{
   93|    399|    return type_str(v.t);
   94|    399|}
vm.cpp:_ZNK7jsonnet8internal12_GLOBAL__N_15Value6isHeapEv:
   67|  49.1M|    {
   68|  49.1M|        return t & 0x10;
   69|  49.1M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_19HeapThunkC2EPKNS0_10IdentifierEPNS1_10HeapObjectEjPKNS0_3ASTE:
  139|  36.8M|    {
  140|  36.8M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_110HeapEntityC2ENS2_4TypeE:
   41|  80.5M|    HeapEntity(Type type_) : type(type_) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_110HeapEntityD2Ev:
   42|  80.5M|    virtual ~HeapEntity() {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap9checkHeapEv:
  465|  80.5M|    {
  466|  80.5M|        return numEntities > gcTuneMinObjects &&
  ------------------
  |  Branch (466:16): [True: 31.8M, False: 48.6M]
  ------------------
  467|  80.5M|               numEntities > gcTuneGrowthTrigger * lastNumEntities;
  ------------------
  |  Branch (467:16): [True: 87.5k, False: 31.7M]
  ------------------
  468|  80.5M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap8markFromEPNS1_10HeapEntityE:
  351|  63.8M|    {
  352|  63.8M|        assert(from != nullptr);
  353|      0|        const GarbageCollectionMark thisMark = lastMark + 1;
  354|  63.8M|        struct State {
  355|  63.8M|            HeapEntity *ent;
  356|  63.8M|            std::vector<HeapEntity *> children;
  357|  63.8M|            State(HeapEntity *ent) : ent(ent) {}
  358|  63.8M|        };
  359|       |
  360|  63.8M|        std::vector<State> stack;
  361|  63.8M|        stack.emplace_back(from);
  362|       |
  363|   277M|        while (stack.size() > 0) {
  ------------------
  |  Branch (363:16): [True: 214M, False: 63.8M]
  ------------------
  364|   214M|            size_t curr_index = stack.size() - 1;
  365|   214M|            State &s = stack[curr_index];
  366|   214M|            HeapEntity *curr = s.ent;
  367|   214M|            if (curr->mark != thisMark) {
  ------------------
  |  Branch (367:17): [True: 56.8M, False: 157M]
  ------------------
  368|  56.8M|                curr->mark = thisMark;
  369|       |
  370|  56.8M|                switch(curr->type) {
  371|  6.71M|                    case HeapEntity::SIMPLE_OBJECT: {
  ------------------
  |  Branch (371:21): [True: 6.71M, False: 50.1M]
  ------------------
  372|  6.71M|                        assert(dynamic_cast<HeapSimpleObject *>(curr));
  373|      0|                        auto *obj = static_cast<HeapSimpleObject *>(curr);
  374|  6.71M|                        for (auto upv : obj->upValues)
  ------------------
  |  Branch (374:39): [True: 4.57M, False: 6.71M]
  ------------------
  375|  4.57M|                            addIfHeapEntity(upv.second, s.children);
  376|  6.71M|                        break;
  377|      0|                    }
  378|  4.28M|                    case HeapEntity::EXTENDED_OBJECT: {
  ------------------
  |  Branch (378:21): [True: 4.28M, False: 52.5M]
  ------------------
  379|  4.28M|                        assert(dynamic_cast<HeapExtendedObject *>(curr));
  380|      0|                        auto *obj = static_cast<HeapExtendedObject *>(curr);
  381|  4.28M|                        addIfHeapEntity(obj->left, s.children);
  382|  4.28M|                        addIfHeapEntity(obj->right, s.children);
  383|  4.28M|                        break;
  384|      0|                    }
  385|      0|                    case HeapEntity::COMPREHENSION_OBJECT: {
  ------------------
  |  Branch (385:21): [True: 0, False: 56.8M]
  ------------------
  386|      0|                        assert(dynamic_cast<HeapComprehensionObject *>(curr));
  387|      0|                        auto *obj = static_cast<HeapComprehensionObject *>(curr);
  388|      0|                        for (auto upv : obj->upValues)
  ------------------
  |  Branch (388:39): [True: 0, False: 0]
  ------------------
  389|      0|                            addIfHeapEntity(upv.second, s.children);
  390|      0|                        for (auto upv : obj->compValues)
  ------------------
  |  Branch (390:39): [True: 0, False: 0]
  ------------------
  391|      0|                            addIfHeapEntity(upv.second, s.children);
  392|      0|                        break;
  393|      0|                    }
  394|  1.25M|                    case HeapEntity::ARRAY: {
  ------------------
  |  Branch (394:21): [True: 1.25M, False: 55.5M]
  ------------------
  395|  1.25M|                        assert(dynamic_cast<HeapArray *>(curr));
  396|      0|                        auto *arr = static_cast<HeapArray *>(curr);
  397|  1.25M|                        for (auto el : arr->elements)
  ------------------
  |  Branch (397:38): [True: 16.8M, False: 1.25M]
  ------------------
  398|  16.8M|                            addIfHeapEntity(el, s.children);
  399|  1.25M|                        break;
  400|      0|                    }
  401|  1.53M|                    case HeapEntity::CLOSURE: {
  ------------------
  |  Branch (401:21): [True: 1.53M, False: 55.2M]
  ------------------
  402|  1.53M|                        assert(dynamic_cast<HeapClosure *>(curr));
  403|      0|                        auto *func = static_cast<HeapClosure *>(curr);
  404|  1.53M|                        for (auto upv : func->upValues)
  ------------------
  |  Branch (404:39): [True: 2.31M, False: 1.53M]
  ------------------
  405|  2.31M|                            addIfHeapEntity(upv.second, s.children);
  406|  1.53M|                        if (func->self)
  ------------------
  |  Branch (406:29): [True: 1.14M, False: 390k]
  ------------------
  407|  1.14M|                            addIfHeapEntity(func->self, s.children);
  408|  1.53M|                        break;
  409|      0|                    }
  410|  41.0M|                    case HeapEntity::THUNK: {
  ------------------
  |  Branch (410:21): [True: 41.0M, False: 15.7M]
  ------------------
  411|  41.0M|                        assert(dynamic_cast<HeapThunk *>(curr));
  412|      0|                        auto *thunk = static_cast<HeapThunk *>(curr);
  413|  41.0M|                        if (thunk->filled) {
  ------------------
  |  Branch (413:29): [True: 9.02M, False: 32.0M]
  ------------------
  414|  9.02M|                            if (thunk->content.isHeap())
  ------------------
  |  Branch (414:33): [True: 6.15M, False: 2.86M]
  ------------------
  415|  6.15M|                                addIfHeapEntity(thunk->content.v.h, s.children);
  416|  32.0M|                        } else {
  417|  32.0M|                            for (auto upv : thunk->upValues)
  ------------------
  |  Branch (417:43): [True: 7.24M, False: 32.0M]
  ------------------
  418|  7.24M|                                addIfHeapEntity(upv.second, s.children);
  419|  32.0M|                            if (thunk->self)
  ------------------
  |  Branch (419:33): [True: 28.2M, False: 3.79M]
  ------------------
  420|  28.2M|                                addIfHeapEntity(thunk->self, s.children);
  421|  32.0M|                        }
  422|  41.0M|                        break;
  423|      0|                    }
  424|  1.97M|                    case HeapEntity::STRING:
  ------------------
  |  Branch (424:21): [True: 1.97M, False: 54.8M]
  ------------------
  425|  1.97M|                        assert(dynamic_cast<HeapString *>(curr));
  426|      0|                        break;
  427|      0|                    default:
  ------------------
  |  Branch (427:21): [True: 0, False: 56.8M]
  ------------------
  428|      0|                        assert(false);
  429|      0|                        break;
  430|  56.8M|                }
  431|  56.8M|            }
  432|       |
  433|   214M|            if (s.children.size() > 0) {
  ------------------
  |  Branch (433:17): [True: 75.0M, False: 138M]
  ------------------
  434|  75.0M|                HeapEntity *next = s.children[s.children.size() - 1];
  435|  75.0M|                s.children.pop_back();
  436|  75.0M|                stack.emplace_back(next);  // CAUTION: s invalidated here
  437|   138M|            } else {
  438|   138M|                stack.pop_back();  // CAUTION: s invalidated here
  439|   138M|            }
  440|   214M|        }
  441|  63.8M|    }
vm.cpp:_ZZN7jsonnet8internal12_GLOBAL__N_14Heap8markFromEPNS1_10HeapEntityEEN5StateC2ES4_:
  357|   138M|            State(HeapEntity *ent) : ent(ent) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap15addIfHeapEntityEPNS1_10HeapEntityERNSt3__16vectorIS4_NS5_9allocatorIS4_EEEE:
  322|  75.0M|    {
  323|  75.0M|        vec.push_back(v);
  324|  75.0M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap8markFromENS1_5ValueE:
  344|  39.7M|    {
  345|  39.7M|        if (v.isHeap())
  ------------------
  |  Branch (345:13): [True: 9.10M, False: 30.6M]
  ------------------
  346|  9.10M|            markFrom(v.v.h);
  347|  39.7M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap5sweepEv:
  445|  91.6k|    {
  446|  91.6k|        lastMark++;
  447|       |        // Heap shrinks during this loop.  Do not cache entities.size().
  448|   137M|        for (unsigned long i = 0; i < entities.size(); ++i) {
  ------------------
  |  Branch (448:35): [True: 137M, False: 91.6k]
  ------------------
  449|   137M|            HeapEntity *x = entities[i];
  450|   137M|            if (x->mark != lastMark) {
  ------------------
  |  Branch (450:17): [True: 80.5M, False: 56.8M]
  ------------------
  451|  80.5M|                delete x;
  452|  80.5M|                if (i != entities.size() - 1) {
  ------------------
  |  Branch (452:21): [True: 80.4M, False: 78.2k]
  ------------------
  453|       |                    // Swap it with the back.
  454|  80.4M|                    entities[i] = entities[entities.size() - 1];
  455|  80.4M|                }
  456|  80.5M|                entities.pop_back();
  457|  80.5M|                --i;
  458|  80.5M|            }
  459|   137M|        }
  460|  91.6k|        lastNumEntities = numEntities = entities.size();
  461|  91.6k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_19HeapThunk4fillERKNS1_5ValueE:
  143|  19.0M|    {
  144|  19.0M|        content = v;
  145|  19.0M|        filled = true;
  146|  19.0M|        self = nullptr;
  147|  19.0M|        upValues.clear();
  148|  19.0M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapArrayEJRKNSt3__16vectorIPNS1_9HeapThunkENS5_9allocatorIS8_EEEEEEEPT_DpOT0_:
  477|  1.11M|    {
  478|  1.11M|        T *r = new T(std::forward<Args>(args)...);
  479|  1.11M|        entities.push_back(r);
  480|  1.11M|        r->mark = lastMark;
  481|  1.11M|        numEntities = entities.size();
  482|  1.11M|        return r;
  483|  1.11M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_19HeapArrayC2ERKNSt3__16vectorIPNS1_9HeapThunkENS3_9allocatorIS6_EEEE:
  158|  1.11M|    {
  159|  1.11M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_10HeapStringEJRKNSt3__112basic_stringIDiNS5_11char_traitsIDiEENS5_9allocatorIDiEEEEEEEPT_DpOT0_:
  477|  31.6M|    {
  478|  31.6M|        T *r = new T(std::forward<Args>(args)...);
  479|  31.6M|        entities.push_back(r);
  480|  31.6M|        r->mark = lastMark;
  481|  31.6M|        numEntities = entities.size();
  482|  31.6M|        return r;
  483|  31.6M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_110HeapStringC2ERKNSt3__112basic_stringIDiNS3_11char_traitsIDiEENS3_9allocatorIDiEEEE:
  281|  31.6M|    HeapString(const UString &value) : HeapEntity(STRING), value(value) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJRPKNS0_10IdentifierEDniDnEEEPT_DpOT0_:
  477|   104k|    {
  478|   104k|        T *r = new T(std::forward<Args>(args)...);
  479|   104k|        entities.push_back(r);
  480|   104k|        r->mark = lastMark;
  481|   104k|        numEntities = entities.size();
  482|   104k|        return r;
  483|   104k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111HeapClosure5ParamC2EPKNS0_10IdentifierEPKNS0_3ASTE:
  259|  13.7M|        Param(const Identifier *id, const AST *def) : id(id), def(def) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_11HeapClosureEJNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEEDniRKNS5_6vectorINS4_5ParamENSE_ISL_EEEERPNS0_3ASTERKNS5_12basic_stringIcNS5_11char_traitsIcEENSE_IcEEEEEEEPT_DpOT0_:
  477|  6.71M|    {
  478|  6.71M|        T *r = new T(std::forward<Args>(args)...);
  479|  6.71M|        entities.push_back(r);
  480|  6.71M|        r->mark = lastMark;
  481|  6.71M|        numEntities = entities.size();
  482|  6.71M|        return r;
  483|  6.71M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111HeapClosureC2ERKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS3_4lessIS7_EENS3_9allocatorINS3_4pairIKS7_S9_EEEEEEPNS1_10HeapObjectEjRKNS3_6vectorINS2_5ParamENSC_ISN_EEEEPKNS0_3ASTERKNS3_12basic_stringIcNS3_11char_traitsIcEENSC_IcEEEE:
  274|  8.39M|    {
  275|  8.39M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_114HeapLeafObjectC2ENS1_10HeapEntity4TypeE:
  164|  1.58M|    HeapLeafObject(Type type) : HeapObject(type) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_110HeapObjectC2ENS1_10HeapEntity4TypeE:
  107|  2.54M|    HeapObject(Type type) : HeapEntity(type) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJDnDniPKNS0_3ASTEEEEPT_DpOT0_:
  477|  4.16k|    {
  478|  4.16k|        T *r = new T(std::forward<Args>(args)...);
  479|  4.16k|        entities.push_back(r);
  480|  4.16k|        r->mark = lastMark;
  481|  4.16k|        numEntities = entities.size();
  482|  4.16k|        return r;
  483|  4.16k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJPNS0_10IdentifierERPNS1_10HeapObjectEiRKPNS0_3ASTEEEEPT_DpOT0_:
  477|   637k|    {
  478|   637k|        T *r = new T(std::forward<Args>(args)...);
  479|   637k|        entities.push_back(r);
  480|   637k|        r->mark = lastMark;
  481|   637k|        numEntities = entities.size();
  482|   637k|        return r;
  483|   637k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14HeapD2Ev:
  337|  4.16k|    {
  338|       |        // Nothing is marked, everything will be collected.
  339|  4.16k|        sweep();
  340|  4.16k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPNS0_3ASTEEEEPT_DpOT0_:
  477|  20.8M|    {
  478|  20.8M|        T *r = new T(std::forward<Args>(args)...);
  479|  20.8M|        entities.push_back(r);
  480|  20.8M|        r->mark = lastMark;
  481|  20.8M|        numEntities = entities.size();
  482|  20.8M|        return r;
  483|  20.8M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_11HeapClosureEJRKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEERPNS1_10HeapObjectERjRKNS5_6vectorINS4_5ParamENSE_ISR_EEEERPNS0_3ASTERA1_KcEEEPT_DpOT0_:
  477|  1.68M|    {
  478|  1.68M|        T *r = new T(std::forward<Args>(args)...);
  479|  1.68M|        entities.push_back(r);
  480|  1.68M|        r->mark = lastMark;
  481|  1.68M|        numEntities = entities.size();
  482|  1.68M|        return r;
  483|  1.68M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJRKPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPNS0_3ASTEEEEPT_DpOT0_:
  477|  15.1M|    {
  478|  15.1M|        T *r = new T(std::forward<Args>(args)...);
  479|  15.1M|        entities.push_back(r);
  480|  15.1M|        r->mark = lastMark;
  481|  15.1M|        numEntities = entities.size();
  482|  15.1M|        return r;
  483|  15.1M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_16HeapSimpleObjectEJRNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEERNS6_IS9_NS4_5FieldESD_NSE_INSF_ISG_SL_EEEEEERNS5_4listIPNS0_3ASTENSE_ISS_EEEEEEEPT_DpOT0_:
  477|  1.58M|    {
  478|  1.58M|        T *r = new T(std::forward<Args>(args)...);
  479|  1.58M|        entities.push_back(r);
  480|  1.58M|        r->mark = lastMark;
  481|  1.58M|        numEntities = entities.size();
  482|  1.58M|        return r;
  483|  1.58M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116HeapSimpleObjectC2ERKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS3_4lessIS7_EENS3_9allocatorINS3_4pairIKS7_S9_EEEEEENS4_IS7_NS2_5FieldESB_NSC_INSD_ISE_SK_EEEEEENS3_4listIPNS0_3ASTENSC_ISQ_EEEE:
  195|  1.58M|    {
  196|  1.58M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPKNS0_3ASTEEEEPT_DpOT0_:
  477|     37|    {
  478|     37|        T *r = new T(std::forward<Args>(args)...);
  479|     37|        entities.push_back(r);
  480|     37|        r->mark = lastMark;
  481|     37|        numEntities = entities.size();
  482|     37|        return r;
  483|     37|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_18HeapExtendedObjectEJRPNS1_10HeapObjectES7_EEEPT_DpOT0_:
  477|   954k|    {
  478|   954k|        T *r = new T(std::forward<Args>(args)...);
  479|   954k|        entities.push_back(r);
  480|   954k|        r->mark = lastMark;
  481|   954k|        numEntities = entities.size();
  482|   954k|        return r;
  483|   954k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_118HeapExtendedObjectC2EPNS1_10HeapObjectES4_:
  209|   954k|    {
  210|   954k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRPNS0_3ASTEEEEPT_DpOT0_:
  477|  65.8k|    {
  478|  65.8k|        T *r = new T(std::forward<Args>(args)...);
  479|  65.8k|        entities.push_back(r);
  480|  65.8k|        r->mark = lastMark;
  481|  65.8k|        numEntities = entities.size();
  482|  65.8k|        return r;
  483|  65.8k|    }

_ZN7jsonnet8internal23jsonnet_static_analysisEPNS0_3ASTE:
  228|  9.28k|{
  229|  9.28k|    static_analysis(ast, false, IdSet{});
  230|  9.28k|}
static_analysis.cpp:_ZN7jsonnet8internalL15static_analysisEPNS0_3ASTEbRKNSt3__13setIPKNS0_10IdentifierENS3_4lessIS7_EENS3_9allocatorIS7_EEEE:
   41|   282M|{
   42|   282M|    IdSet r;
   43|       |
   44|   282M|    switch (ast_->type) {
   45|  25.4M|    case AST_APPLY: {
  ------------------
  |  Branch (45:5): [True: 25.4M, False: 256M]
  ------------------
   46|  25.4M|        assert(dynamic_cast<Apply *>(ast_));
   47|      0|        auto* ast = static_cast<Apply *>(ast_);
   48|  25.4M|        append(r, static_analysis(ast->target, in_object, vars));
   49|  25.4M|        for (const auto &arg : ast->args)
  ------------------
  |  Branch (49:30): [True: 41.9M, False: 25.4M]
  ------------------
   50|  41.9M|            append(r, static_analysis(arg.expr, in_object, vars));
   51|  25.4M|    } break;
   52|      0|    case AST_APPLY_BRACE: {
  ------------------
  |  Branch (52:5): [True: 0, False: 282M]
  ------------------
   53|      0|        assert(dynamic_cast<ApplyBrace *>(ast_));
   54|       |        // Nothing to do.
   55|      0|    } break;
   56|  5.83M|    case AST_ARRAY: {
  ------------------
  |  Branch (56:5): [True: 5.83M, False: 276M]
  ------------------
   57|  5.83M|        assert(dynamic_cast<Array *>(ast_));
   58|      0|        auto* ast = static_cast<Array *>(ast_);
   59|  5.83M|        for (auto &el : ast->elements)
  ------------------
  |  Branch (59:23): [True: 9.40M, False: 5.83M]
  ------------------
   60|  9.40M|            append(r, static_analysis(el.expr, in_object, vars));
   61|  5.83M|    } break;
   62|  25.6M|    case AST_BINARY: {
  ------------------
  |  Branch (62:5): [True: 25.6M, False: 256M]
  ------------------
   63|  25.6M|        assert(dynamic_cast<Binary *>(ast_));
   64|      0|        auto* ast = static_cast<Binary *>(ast_);
   65|  25.6M|        append(r, static_analysis(ast->left, in_object, vars));
   66|  25.6M|        append(r, static_analysis(ast->right, in_object, vars));
   67|  25.6M|    } break;
   68|   361k|    case AST_BUILTIN_FUNCTION: {
  ------------------
  |  Branch (68:5): [True: 361k, False: 281M]
  ------------------
   69|   361k|        assert(dynamic_cast<BuiltinFunction *>(ast_));
   70|       |        // Nothing to do.
   71|   361k|    } break;
   72|  10.3M|    case AST_CONDITIONAL: {
  ------------------
  |  Branch (72:5): [True: 10.3M, False: 271M]
  ------------------
   73|  10.3M|        assert(dynamic_cast<Conditional *>(ast_));
   74|      0|        auto* ast = static_cast<Conditional *>(ast_);
   75|  10.3M|        append(r, static_analysis(ast->cond, in_object, vars));
   76|  10.3M|        append(r, static_analysis(ast->branchTrue, in_object, vars));
   77|  10.3M|        append(r, static_analysis(ast->branchFalse, in_object, vars));
   78|  10.3M|    } break;
   79|  5.40M|    case AST_ERROR: {
  ------------------
  |  Branch (79:5): [True: 5.40M, False: 276M]
  ------------------
   80|  5.40M|        assert(dynamic_cast<Error *>(ast_));
   81|      0|        auto* ast = static_cast<Error *>(ast_);
   82|  5.40M|        append(r, static_analysis(ast->expr, in_object, vars));
   83|  5.40M|    } break;
   84|  6.43M|    case AST_FUNCTION: {
  ------------------
  |  Branch (84:5): [True: 6.43M, False: 275M]
  ------------------
   85|  6.43M|        assert(dynamic_cast<Function *>(ast_));
   86|      0|        auto* ast = static_cast<Function *>(ast_);
   87|  6.43M|        auto new_vars = vars;
   88|  6.43M|        IdSet params;
   89|  11.7M|        for (const auto &p : ast->params) {
  ------------------
  |  Branch (89:28): [True: 11.7M, False: 6.43M]
  ------------------
   90|  11.7M|            if (params.find(p.id) != params.end()) {
  ------------------
  |  Branch (90:17): [True: 20, False: 11.7M]
  ------------------
   91|     20|                std::string msg = "Duplicate function parameter: " + encode_utf8(p.id->name);
   92|     20|                throw StaticError(ast_->location, msg);
   93|     20|            }
   94|  11.7M|            params.insert(p.id);
   95|  11.7M|            new_vars.insert(p.id);
   96|  11.7M|        }
   97|       |
   98|  6.43M|        auto fv = static_analysis(ast->body, in_object, new_vars);
   99|  11.7M|        for (const auto &p : ast->params) {
  ------------------
  |  Branch (99:28): [True: 11.7M, False: 6.43M]
  ------------------
  100|  11.7M|            if (p.expr != nullptr)
  ------------------
  |  Branch (100:17): [True: 195k, False: 11.5M]
  ------------------
  101|   195k|                append(fv, static_analysis(p.expr, in_object, new_vars));
  102|  11.7M|        }
  103|  6.43M|        for (const auto &p : ast->params)
  ------------------
  |  Branch (103:28): [True: 11.7M, False: 6.43M]
  ------------------
  104|  11.7M|            fv.erase(p.id);
  105|  6.43M|        append(r, fv);
  106|  6.43M|    } break;
  107|    453|    case AST_IMPORT: {
  ------------------
  |  Branch (107:5): [True: 453, False: 282M]
  ------------------
  108|    453|        assert(dynamic_cast<Import *>(ast_));
  109|       |        // Nothing to do.
  110|    453|    } break;
  111|    263|    case AST_IMPORTSTR: {
  ------------------
  |  Branch (111:5): [True: 263, False: 282M]
  ------------------
  112|    263|        assert(dynamic_cast<Importstr *>(ast_));
  113|       |        // Nothing to do.
  114|    263|    } break;
  115|    143|    case AST_IMPORTBIN: {
  ------------------
  |  Branch (115:5): [True: 143, False: 282M]
  ------------------
  116|    143|        assert(dynamic_cast<Importbin *>(ast_));
  117|       |        // Nothing to do.
  118|    143|    } break;
  119|  55.1k|    case AST_IN_SUPER: {
  ------------------
  |  Branch (119:5): [True: 55.1k, False: 282M]
  ------------------
  120|  55.1k|        assert(dynamic_cast<const InSuper *>(ast_));
  121|      0|        auto* ast = static_cast<const InSuper *>(ast_);
  122|  55.1k|        if (!in_object)
  ------------------
  |  Branch (122:13): [True: 14, False: 55.1k]
  ------------------
  123|     14|            throw StaticError(ast_->location, "Can't use super outside of an object.");
  124|  55.1k|        append(r, static_analysis(ast->element, in_object, vars));
  125|  55.1k|    } break;
  126|  27.8M|    case AST_INDEX: {
  ------------------
  |  Branch (126:5): [True: 27.8M, False: 254M]
  ------------------
  127|  27.8M|        assert(dynamic_cast<const Index *>(ast_));
  128|      0|        auto* ast = static_cast<const Index *>(ast_);
  129|  27.8M|        append(r, static_analysis(ast->target, in_object, vars));
  130|  27.8M|        append(r, static_analysis(ast->index, in_object, vars));
  131|  27.8M|    } break;
  132|  13.3M|    case AST_LOCAL: {
  ------------------
  |  Branch (132:5): [True: 13.3M, False: 268M]
  ------------------
  133|  13.3M|        assert(dynamic_cast<const Local *>(ast_));
  134|      0|        auto* ast = static_cast<const Local *>(ast_);
  135|  13.3M|        IdSet ast_vars;
  136|  22.4M|        for (const auto &bind : ast->binds) {
  ------------------
  |  Branch (136:31): [True: 22.4M, False: 13.3M]
  ------------------
  137|  22.4M|            ast_vars.insert(bind.var);
  138|  22.4M|        }
  139|  13.3M|        auto new_vars = vars;
  140|  13.3M|        append(new_vars, ast_vars);
  141|  13.3M|        IdSet fvs;
  142|  22.3M|        for (const auto &bind : ast->binds) {
  ------------------
  |  Branch (142:31): [True: 22.3M, False: 13.3M]
  ------------------
  143|  22.3M|            append(fvs, static_analysis(bind.body, in_object, new_vars));
  144|  22.3M|        }
  145|       |
  146|  13.3M|        append(fvs, static_analysis(ast->body, in_object, new_vars));
  147|       |
  148|  13.3M|        for (const auto &bind : ast->binds)
  ------------------
  |  Branch (148:31): [True: 22.3M, False: 13.3M]
  ------------------
  149|  22.3M|            fvs.erase(bind.var);
  150|       |
  151|  13.3M|        append(r, fvs);
  152|  13.3M|    } break;
  153|   781k|    case AST_LITERAL_BOOLEAN: {
  ------------------
  |  Branch (153:5): [True: 781k, False: 281M]
  ------------------
  154|   781k|        assert(dynamic_cast<const LiteralBoolean *>(ast_));
  155|       |        // Nothing to do.
  156|   781k|    } break;
  157|  19.4M|    case AST_LITERAL_NUMBER: {
  ------------------
  |  Branch (157:5): [True: 19.4M, False: 262M]
  ------------------
  158|  19.4M|        assert(dynamic_cast<const LiteralNumber *>(ast_));
  159|       |        // Nothing to do.
  160|  19.4M|    } break;
  161|  49.1M|    case AST_LITERAL_STRING: {
  ------------------
  |  Branch (161:5): [True: 49.1M, False: 232M]
  ------------------
  162|  49.1M|        assert(dynamic_cast<const LiteralString *>(ast_));
  163|       |        // Nothing to do.
  164|  49.1M|    } break;
  165|   484k|    case AST_LITERAL_NULL: {
  ------------------
  |  Branch (165:5): [True: 484k, False: 281M]
  ------------------
  166|   484k|        assert(dynamic_cast<const LiteralNull *>(ast_));
  167|       |        // Nothing to do.
  168|   484k|    } break;
  169|  1.63M|    case AST_DESUGARED_OBJECT: {
  ------------------
  |  Branch (169:5): [True: 1.63M, False: 280M]
  ------------------
  170|  1.63M|        assert(dynamic_cast<DesugaredObject *>(ast_));
  171|      0|        auto* ast = static_cast<DesugaredObject *>(ast_);
  172|  7.69M|        for (auto &field : ast->fields) {
  ------------------
  |  Branch (172:26): [True: 7.69M, False: 1.63M]
  ------------------
  173|  7.69M|            append(r, static_analysis(field.name, in_object, vars));
  174|  7.69M|            append(r, static_analysis(field.body, true, vars));
  175|  7.69M|        }
  176|  1.63M|        for (AST *assert : ast->asserts) {
  ------------------
  |  Branch (176:26): [True: 30.0k, False: 1.63M]
  ------------------
  177|  30.0k|            append(r, static_analysis(assert, true, vars));
  178|  30.0k|        }
  179|  1.63M|    } break;
  180|  1.09M|    case AST_OBJECT_COMPREHENSION_SIMPLE: {
  ------------------
  |  Branch (180:5): [True: 1.09M, False: 280M]
  ------------------
  181|  1.09M|        assert(dynamic_cast<ObjectComprehensionSimple *>(ast_));
  182|      0|        auto* ast = static_cast<ObjectComprehensionSimple *>(ast_);
  183|  1.09M|        auto new_vars = vars;
  184|  1.09M|        new_vars.insert(ast->id);
  185|  1.09M|        append(r, static_analysis(ast->field, false, new_vars));
  186|  1.09M|        append(r, static_analysis(ast->value, true, new_vars));
  187|  1.09M|        r.erase(ast->id);
  188|  1.09M|        append(r, static_analysis(ast->array, in_object, vars));
  189|  1.09M|    } break;
  190|  2.16M|    case AST_SELF: {
  ------------------
  |  Branch (190:5): [True: 2.16M, False: 279M]
  ------------------
  191|  2.16M|        assert(dynamic_cast<const Self *>(ast_));
  192|  2.16M|        if (!in_object)
  ------------------
  |  Branch (192:13): [True: 4, False: 2.16M]
  ------------------
  193|      4|            throw StaticError(ast_->location, "Can't use self outside of an object.");
  194|  2.16M|    } break;
  195|  2.16M|    case AST_SUPER_INDEX: {
  ------------------
  |  Branch (195:5): [True: 55.1k, False: 282M]
  ------------------
  196|  55.1k|        assert(dynamic_cast<const SuperIndex *>(ast_));
  197|      0|        auto* ast = static_cast<const SuperIndex *>(ast_);
  198|  55.1k|        if (!in_object)
  ------------------
  |  Branch (198:13): [True: 18, False: 55.1k]
  ------------------
  199|     18|            throw StaticError(ast_->location, "Can't use super outside of an object.");
  200|  55.1k|        append(r, static_analysis(ast->index, in_object, vars));
  201|  55.1k|    } break;
  202|   793k|    case AST_UNARY: {
  ------------------
  |  Branch (202:5): [True: 793k, False: 281M]
  ------------------
  203|   793k|        assert(dynamic_cast<const Unary *>(ast_));
  204|      0|        auto* ast = static_cast<const Unary *>(ast_);
  205|   793k|        append(r, static_analysis(ast->expr, in_object, vars));
  206|   793k|    } break;
  207|  85.7M|    case AST_VAR: {
  ------------------
  |  Branch (207:5): [True: 85.7M, False: 196M]
  ------------------
  208|  85.7M|        assert(dynamic_cast<const Var *>(ast_));
  209|      0|        auto* ast = static_cast<const Var *>(ast_);
  210|  85.7M|        if (vars.find(ast->id) == vars.end()) {
  ------------------
  |  Branch (210:13): [True: 888, False: 85.7M]
  ------------------
  211|    888|            throw StaticError(ast->location, "Unknown variable: " + encode_utf8(ast->id->name));
  212|    888|        }
  213|  85.7M|        r.insert(ast->id);
  214|  85.7M|    } break;
  215|      0|    default:
  ------------------
  |  Branch (215:5): [True: 0, False: 282M]
  ------------------
  216|      0|        std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
  217|      0|        std::abort();
  218|      0|        break;
  219|   282M|    }
  220|       |
  221|   282M|    for (auto *id : r)
  ------------------
  |  Branch (221:19): [True: 369M, False: 282M]
  ------------------
  222|   369M|        ast_->freeVariables.push_back(id);
  223|       |
  224|   282M|    return r;
  225|   282M|}
static_analysis.cpp:_ZN7jsonnet8internalL6appendERNSt3__13setIPKNS0_10IdentifierENS1_4lessIS5_EENS1_9allocatorIS5_EEEERKSA_:
   29|   308M|{
   30|   308M|    r.insert(s.begin(), s.end());
   31|   308M|}

libjsonnet.cpp:_ZN7jsonnet8internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_11StaticErrorE:
  108|  5.10k|{
  109|  5.10k|    o << err.toString();
  110|  5.10k|    return o;
  111|  5.10k|}
_ZNK7jsonnet8internal11StaticError8toStringEv:
   97|  5.10k|    {
   98|  5.10k|        std::stringstream ss;
   99|  5.10k|        if (location.isSet()) {
  ------------------
  |  Branch (99:13): [True: 5.10k, False: 1]
  ------------------
  100|  5.10k|            ss << location << ":";
  101|  5.10k|        }
  102|  5.10k|        ss << " " << msg;
  103|  5.10k|        return ss.str();
  104|  5.10k|    }
_ZNK7jsonnet8internal13LocationRange5isSetEv:
   58|   369k|    {
   59|   369k|        return begin.isSet();
   60|   369k|    }
_ZNK7jsonnet8internal8Location5isSetEv:
   31|   369k|    {
   32|   369k|        return line != 0;
   33|   369k|    }
libjsonnet.cpp:_ZN7jsonnet8internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_13LocationRangeE:
   64|  27.1k|{
   65|  27.1k|    if (loc.file.length() > 0)
  ------------------
  |  Branch (65:9): [True: 10.7k, False: 16.3k]
  ------------------
   66|  10.7k|        o << loc.file;
   67|  27.1k|    if (loc.isSet()) {
  ------------------
  |  Branch (67:9): [True: 25.4k, False: 1.69k]
  ------------------
   68|  25.4k|        if (loc.file.length() > 0)
  ------------------
  |  Branch (68:13): [True: 9.18k, False: 16.3k]
  ------------------
   69|  9.18k|            o << ":";
   70|  25.4k|        if (loc.begin.line == loc.end.line) {
  ------------------
  |  Branch (70:13): [True: 22.0k, False: 3.48k]
  ------------------
   71|  22.0k|            if (loc.begin.column == loc.end.column - 1) {
  ------------------
  |  Branch (71:17): [True: 5.05k, False: 16.9k]
  ------------------
   72|  5.05k|                o << loc.begin;
   73|  16.9k|            } else {
   74|  16.9k|                o << loc.begin << "-" << loc.end.column;
   75|  16.9k|            }
   76|  22.0k|        } else {
   77|  3.48k|            o << "(" << loc.begin << ")-(" << loc.end << ")";
   78|  3.48k|        }
   79|  25.4k|    }
   80|  27.1k|    return o;
   81|  27.1k|}
libjsonnet.cpp:_ZN7jsonnet8internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_8LocationE:
   41|  28.9k|{
   42|  28.9k|    o << loc.line << ":" << loc.column;
   43|  28.9k|    return o;
   44|  28.9k|}
_ZN7jsonnet8internal8LocationC2Ev:
   28|  5.40M|    Location(void) : line(0), column(0) {}
_ZN7jsonnet8internal8LocationC2Emm:
   29|   268M|    Location(unsigned long line, unsigned long column) : line(line), column(column) {}
_ZNK7jsonnet8internal8Location9successorEv:
   35|    614|    {
   36|    614|        return Location(this->line, this->column + 1);
   37|    614|    }
_ZN7jsonnet8internal13LocationRangeC2Ev:
   50|  2.69M|    LocationRange(void) {}
_ZN7jsonnet8internal13LocationRangeC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   52|  7.43k|    LocationRange(const std::string &msg) : file(msg) {}
_ZN7jsonnet8internal13LocationRangeC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS0_8LocationESD_:
   55|   205M|    {
   56|   205M|    }
_ZN7jsonnet8internal11StaticErrorC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS0_8LocationESA_:
   89|    614|    {
   90|    614|    }
_ZN7jsonnet8internal11StaticErrorC2ERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
   93|  4.49k|    {
   94|  4.49k|    }

_ZN7jsonnet8internal22jsonnet_string_unparseERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEEb:
   25|   471k|{
   26|   471k|    UStringStream ss;
   27|   471k|    ss << (single ? U'\'' : U'\"');
  ------------------
  |  Branch (27:12): [True: 0, False: 471k]
  ------------------
   28|   471k|    ss << jsonnet_string_escape(str, single);
   29|   471k|    ss << (single ? U'\'' : U'\"');
  ------------------
  |  Branch (29:12): [True: 0, False: 471k]
  ------------------
   30|   471k|    return ss.str();
   31|   471k|}
_ZN7jsonnet8internal21jsonnet_string_escapeERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEEb:
   34|   472k|{
   35|   472k|    UStringStream ss;
   36|  1.39G|    for (std::size_t i = 0; i < str.length(); ++i) {
  ------------------
  |  Branch (36:29): [True: 1.39G, False: 472k]
  ------------------
   37|  1.39G|        char32_t c = str[i];
   38|  1.39G|        switch (c) {
   39|   745k|            case U'\"': ss << (single ? U"\"" : U"\\\""); break;
  ------------------
  |  Branch (39:13): [True: 745k, False: 1.39G]
  |  Branch (39:32): [True: 0, False: 745k]
  ------------------
   40|   719k|            case U'\'': ss << (single ? U"\\\'" : U"\'"); break;
  ------------------
  |  Branch (40:13): [True: 719k, False: 1.39G]
  |  Branch (40:32): [True: 0, False: 719k]
  ------------------
   41|  1.28G|            case U'\\': ss << U"\\\\"; break;
  ------------------
  |  Branch (41:13): [True: 1.28G, False: 108M]
  ------------------
   42|   364k|            case U'\b': ss << U"\\b"; break;
  ------------------
  |  Branch (42:13): [True: 364k, False: 1.39G]
  ------------------
   43|   388k|            case U'\f': ss << U"\\f"; break;
  ------------------
  |  Branch (43:13): [True: 388k, False: 1.39G]
  ------------------
   44|  29.8M|            case U'\n': ss << U"\\n"; break;
  ------------------
  |  Branch (44:13): [True: 29.8M, False: 1.36G]
  ------------------
   45|  1.92M|            case U'\r': ss << U"\\r"; break;
  ------------------
  |  Branch (45:13): [True: 1.92M, False: 1.39G]
  ------------------
   46|   119k|            case U'\t': ss << U"\\t"; break;
  ------------------
  |  Branch (46:13): [True: 119k, False: 1.39G]
  ------------------
   47|  2.48k|            case U'\0': ss << U"\\u0000"; break;
  ------------------
  |  Branch (47:13): [True: 2.48k, False: 1.39G]
  ------------------
   48|  74.2M|            default: {
  ------------------
  |  Branch (48:13): [True: 74.2M, False: 1.32G]
  ------------------
   49|  74.2M|                if (c < 0x20 || (c >= 0x7f && c <= 0x9f)) {
  ------------------
  |  Branch (49:21): [True: 19.1M, False: 55.1M]
  |  Branch (49:34): [True: 19.2M, False: 35.9M]
  |  Branch (49:47): [True: 2.42M, False: 16.7M]
  ------------------
   50|       |                    // Unprintable, use \u
   51|  21.5M|                    std::stringstream ss8;
   52|  21.5M|                    ss8 << "\\u" << std::hex << std::setfill('0') << std::setw(4)
   53|  21.5M|                        << (unsigned long)(c);
   54|  21.5M|                    ss << decode_utf8(ss8.str());
   55|  52.7M|                } else {
   56|       |                    // Printable, write verbatim
   57|  52.7M|                    ss << c;
   58|  52.7M|                }
   59|  74.2M|            }
   60|  1.39G|        }
   61|  1.39G|    }
   62|   472k|    return ss.str();
   63|   472k|}
_ZN7jsonnet8internal28jsonnet_string_parse_unicodeERKNS0_13LocationRangeEPKDi:
   66|  24.4k|{
   67|  24.4k|    unsigned long codepoint = 0;
   68|       |    // Expect 4 hex digits.
   69|   121k|    for (unsigned i = 0; i < 4; ++i) {
  ------------------
  |  Branch (69:26): [True: 97.6k, False: 24.3k]
  ------------------
   70|  97.6k|        auto x = (unsigned char)(c[i]);
   71|  97.6k|        unsigned digit;
   72|  97.6k|        if (x == '\0') {
  ------------------
  |  Branch (72:13): [True: 31, False: 97.6k]
  ------------------
   73|     31|            auto msg = "Truncated unicode escape sequence in string literal.";
   74|     31|            throw StaticError(loc, msg);
   75|  97.6k|        } else if (x >= '0' && x <= '9') {
  ------------------
  |  Branch (75:20): [True: 97.6k, False: 22]
  |  Branch (75:32): [True: 78.7k, False: 18.8k]
  ------------------
   76|  78.7k|            digit = x - '0';
   77|  78.7k|        } else if (x >= 'a' && x <= 'f') {
  ------------------
  |  Branch (77:20): [True: 3.76k, False: 15.0k]
  |  Branch (77:32): [True: 3.73k, False: 31]
  ------------------
   78|  3.73k|            digit = x - 'a' + 10;
   79|  15.0k|        } else if (x >= 'A' && x <= 'F') {
  ------------------
  |  Branch (79:20): [True: 15.0k, False: 36]
  |  Branch (79:32): [True: 15.0k, False: 55]
  ------------------
   80|  15.0k|            digit = x - 'A' + 10;
   81|  15.0k|        } else {
   82|     91|            std::stringstream ss;
   83|     91|            ss << "Malformed unicode escape character, "
   84|     91|               << "should be hex: '" << x << "'";
   85|     91|            throw StaticError(loc, ss.str());
   86|     91|        }
   87|  97.5k|        codepoint *= 16;
   88|  97.5k|        codepoint += digit;
   89|  97.5k|    }
   90|  24.3k|    return codepoint;
   91|  24.4k|}
_ZN7jsonnet8internal16is_bmp_codepointEm:
   94|  23.2k|{
   95|  23.2k|    return codepoint < 0xd800 || (codepoint >= 0xe000 && codepoint < 0x10000);
  ------------------
  |  Branch (95:12): [True: 21.5k, False: 1.76k]
  |  Branch (95:35): [True: 672, False: 1.09k]
  |  Branch (95:58): [True: 672, False: 0]
  ------------------
   96|  23.2k|}
_ZN7jsonnet8internal23decode_utf16_surrogatesERKNS0_13LocationRangeEmm:
   99|  1.04k|{
  100|  1.04k|    if (high >= 0xd800 && high < 0xdc00 && low >= 0xdc00 && low < 0xe000) {
  ------------------
  |  Branch (100:9): [True: 1.04k, False: 0]
  |  Branch (100:27): [True: 1.04k, False: 1]
  |  Branch (100:44): [True: 1.02k, False: 22]
  |  Branch (100:61): [True: 1.02k, False: 1]
  ------------------
  101|  1.02k|        return 0x10000 + ((high & 0x03ff) << 10) + (low & 0x03ff);
  102|  1.02k|    } else {
  103|     24|        std::stringstream ss;
  104|     24|        ss << "Invalid UTF-16 bytes";
  105|     24|        throw StaticError(loc, ss.str());
  106|     24|    }
  107|  1.04k|}
_ZN7jsonnet8internal23jsonnet_string_unescapeERKNS0_13LocationRangeERKNSt3__112basic_stringIDiNS4_11char_traitsIDiEENS4_9allocatorIDiEEEE:
  110|  11.2M|{
  111|  11.2M|    UString r;
  112|  11.2M|    const char32_t *s_ptr = s.c_str();
  113|   134M|    for (const char32_t *c = s_ptr; *c != U'\0'; ++c) {
  ------------------
  |  Branch (113:37): [True: 123M, False: 11.2M]
  ------------------
  114|   123M|        switch (*c) {
  115|   502k|            case '\\':
  ------------------
  |  Branch (115:13): [True: 502k, False: 122M]
  ------------------
  116|   502k|                switch (*(++c)) {
  117|  20.3k|                    case '"':
  ------------------
  |  Branch (117:21): [True: 20.3k, False: 481k]
  ------------------
  118|  21.9k|                    case '\'': r += *c; break;
  ------------------
  |  Branch (118:21): [True: 1.62k, False: 500k]
  ------------------
  119|       |
  120|   101k|                    case '\\': r += *c; break;
  ------------------
  |  Branch (120:21): [True: 101k, False: 401k]
  ------------------
  121|       |
  122|  4.75k|                    case '/': r += *c; break;
  ------------------
  |  Branch (122:21): [True: 4.75k, False: 497k]
  ------------------
  123|       |
  124|  9.61k|                    case 'b': r += '\b'; break;
  ------------------
  |  Branch (124:21): [True: 9.61k, False: 492k]
  ------------------
  125|       |
  126|  26.7k|                    case 'f': r += '\f'; break;
  ------------------
  |  Branch (126:21): [True: 26.7k, False: 475k]
  ------------------
  127|       |
  128|   260k|                    case 'n': r += '\n'; break;
  ------------------
  |  Branch (128:21): [True: 260k, False: 241k]
  ------------------
  129|       |
  130|  20.0k|                    case 'r': r += '\r'; break;
  ------------------
  |  Branch (130:21): [True: 20.0k, False: 482k]
  ------------------
  131|       |
  132|  33.9k|                    case 't': r += '\t'; break;
  ------------------
  |  Branch (132:21): [True: 33.9k, False: 468k]
  ------------------
  133|       |
  134|  23.3k|                    case 'u': {
  ------------------
  |  Branch (134:21): [True: 23.3k, False: 478k]
  ------------------
  135|  23.3k|                        ++c;  // Consume the 'u'.
  136|  23.3k|                        unsigned long codepoint = jsonnet_string_parse_unicode(loc, c);
  137|       |
  138|       |                        // Leave us on the last char, ready for the ++c at
  139|       |                        // the outer for loop.
  140|  23.3k|                        c += 3;
  141|  23.3k|                        if (!is_bmp_codepoint(codepoint)) {
  ------------------
  |  Branch (141:29): [True: 1.09k, False: 22.3k]
  ------------------
  142|  1.09k|                           if (*(++c) != '\\') {
  ------------------
  |  Branch (142:32): [True: 28, False: 1.06k]
  ------------------
  143|     28|                                std::stringstream ss;
  144|     28|                                ss << "Invalid non-BMP Unicode escape in string literal";
  145|     28|                                throw StaticError(loc, ss.str());
  146|     28|                           }
  147|  1.06k|                           if (*(++c) != 'u') {
  ------------------
  |  Branch (147:32): [True: 5, False: 1.06k]
  ------------------
  148|      5|                                std::stringstream ss;
  149|      5|                                ss << "Invalid non-BMP Unicode escape in string literal";
  150|      5|                                throw StaticError(loc, ss.str());
  151|      5|                           }
  152|  1.06k|                           ++c;
  153|  1.06k|                           unsigned long codepoint2 = jsonnet_string_parse_unicode(loc, c);
  154|  1.06k|                           c += 3;
  155|  1.06k|                           codepoint = decode_utf16_surrogates(loc, codepoint, codepoint2);
  156|  1.06k|                       }
  157|  23.3k|                       r += codepoint;
  158|  23.3k|                    } break;
  159|       |
  160|      2|                    case '\0': {
  ------------------
  |  Branch (160:21): [True: 2, False: 502k]
  ------------------
  161|      2|                        auto msg = "Truncated escape sequence in string literal.";
  162|      2|                        throw StaticError(loc, msg);
  163|  23.3k|                    }
  164|       |
  165|    151|                    default: {
  ------------------
  |  Branch (165:21): [True: 151, False: 502k]
  ------------------
  166|    151|                        std::stringstream ss;
  167|    151|                        std::string utf8;
  168|    151|                        encode_utf8(*c, utf8);
  169|    151|                        ss << "Unknown escape sequence in string literal: '" << utf8 << "'";
  170|    151|                        throw StaticError(loc, ss.str());
  171|  23.3k|                    }
  172|   502k|                }
  173|   501k|                break;
  174|       |
  175|   122M|            default:
  ------------------
  |  Branch (175:13): [True: 122M, False: 502k]
  ------------------
  176|       |                // Just a regular letter.
  177|   122M|                r += *c;
  178|   123M|        }
  179|   123M|    }
  180|  11.2M|    return r;
  181|  11.2M|}

_ZN7jsonnet8internal13UStringStreamlsERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEE:
  155|  27.4M|    {
  156|  27.4M|        buf.append(s);
  157|  27.4M|        return *this;
  158|  27.4M|    }
_ZN7jsonnet8internal13UStringStreamlsEPKDi:
  160|  1.32G|    {
  161|  1.32G|        buf.append(s);
  162|  1.32G|        return *this;
  163|  1.32G|    }
_ZN7jsonnet8internal13UStringStreamlsEDi:
  165|  53.6M|    {
  166|  53.6M|        buf.push_back(c);
  167|  53.6M|        return *this;
  168|  53.6M|    }
_ZN7jsonnet8internal13UStringStream3strEv:
  179|  5.26M|    {
  180|  5.26M|        return buf;
  181|  5.26M|    }
parser.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  140|  45.2M|{
  141|  45.2M|    UString r;
  142|   312M|    for (size_t i = 0; i < s.length(); ++i)
  ------------------
  |  Branch (142:24): [True: 266M, False: 45.2M]
  ------------------
  143|   266M|        r.push_back(decode_utf8(s, i));
  144|  45.2M|    return r;
  145|  45.2M|}
parser.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   75|   266M|{
   76|   266M|    char c0 = str[i];
   77|   266M|    if ((c0 & 0x80) == 0) {  // 0xxxxxxx
  ------------------
  |  Branch (77:9): [True: 263M, False: 3.44M]
  ------------------
   78|   263M|        return c0;
   79|   263M|    } else if ((c0 & 0xE0) == 0xC0) {  // 110yyyxx 10xxxxxx
  ------------------
  |  Branch (79:16): [True: 282k, False: 3.15M]
  ------------------
   80|   282k|        if (i + 1 >= str.length()) {
  ------------------
  |  Branch (80:13): [True: 5.39k, False: 276k]
  ------------------
   81|  5.39k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  5.39k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   82|  5.39k|        }
   83|   276k|        char c1 = str[++i];
   84|   276k|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (84:13): [True: 235k, False: 41.2k]
  ------------------
   85|   235k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|   235k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   86|   235k|        }
   87|  41.2k|        return ((c0 & 0x1F) << 6ul) | (c1 & 0x3F);
   88|  3.15M|    } else if ((c0 & 0xF0) == 0xE0) {  // 1110yyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (88:16): [True: 388k, False: 2.77M]
  ------------------
   89|   388k|        if (i + 2 >= str.length()) {
  ------------------
  |  Branch (89:13): [True: 2.73k, False: 386k]
  ------------------
   90|  2.73k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  2.73k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   91|  2.73k|        }
   92|   386k|        char c1 = str[++i];
   93|   386k|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (93:13): [True: 351k, False: 34.5k]
  ------------------
   94|   351k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|   351k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   95|   351k|        }
   96|  34.5k|        char c2 = str[++i];
   97|  34.5k|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (97:13): [True: 18.1k, False: 16.3k]
  ------------------
   98|  18.1k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  18.1k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   99|  18.1k|        }
  100|  16.3k|        return ((c0 & 0xF) << 12ul) | ((c1 & 0x3F) << 6) | (c2 & 0x3F);
  101|  2.77M|    } else if ((c0 & 0xF8) == 0xF0) {  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (101:16): [True: 103k, False: 2.66M]
  ------------------
  102|   103k|        if (i + 3 >= str.length()) {
  ------------------
  |  Branch (102:13): [True: 2.44k, False: 100k]
  ------------------
  103|  2.44k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  2.44k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  104|  2.44k|        }
  105|   100k|        char c1 = str[++i];
  106|   100k|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (106:13): [True: 84.7k, False: 16.0k]
  ------------------
  107|  84.7k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  84.7k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  108|  84.7k|        }
  109|  16.0k|        char c2 = str[++i];
  110|  16.0k|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (110:13): [True: 2.36k, False: 13.7k]
  ------------------
  111|  2.36k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  2.36k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  112|  2.36k|        }
  113|  13.7k|        char c3 = str[++i];
  114|  13.7k|        if ((c3 & 0xC0) != 0x80) {
  ------------------
  |  Branch (114:13): [True: 9.09k, False: 4.61k]
  ------------------
  115|  9.09k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  9.09k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  116|  9.09k|        }
  117|  4.61k|        return ((c0 & 0x7) << 24ul) | ((c1 & 0x3F) << 12ul) | ((c2 & 0x3F) << 6) | (c3 & 0x3F);
  118|  2.66M|    } else {
  119|  2.66M|        return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  2.66M|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  120|  2.66M|    }
  121|   266M|}
static_analysis.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEE:
  133|    908|{
  134|    908|    std::string r;
  135|    908|    encode_utf8(s, r);
  136|    908|    return r;
  137|    908|}
static_analysis.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEERNS2_IcNS3_IcEENS5_IcEEEE:
  127|    908|{
  128|    908|    for (char32_t cp : s)
  ------------------
  |  Branch (128:22): [True: 9.31M, False: 908]
  ------------------
  129|  9.31M|        encode_utf8(cp, r);
  130|    908|}
static_analysis.cpp:_ZN7jsonnet8internalL11encode_utf8EDiRNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   33|  9.31M|{
   34|  9.31M|    if (x >= JSONNET_CODEPOINT_MAX)
  ------------------
  |  |   22|  9.31M|#define JSONNET_CODEPOINT_MAX 0x110000
  ------------------
  |  Branch (34:9): [True: 0, False: 9.31M]
  ------------------
   35|      0|        x = JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   36|       |
   37|       |    // 00ZZZzzz 00zzYYYY 00Yyyyxx 00xxxxxx
   38|  9.31M|    long bytes = ((x & 0x1C0000) << 6) | ((x & 0x03F000) << 4) | ((x & 0x0FC0) << 2) | (x & 0x3F);
   39|       |
   40|  9.31M|    if (x < 0x80) {
  ------------------
  |  Branch (40:9): [True: 9.31M, False: 0]
  ------------------
   41|  9.31M|        s.push_back((char)x);
   42|  9.31M|        return 1;
   43|  9.31M|    } else if (x < 0x800) {  // note that capital 'Y' bits must be 0
  ------------------
  |  Branch (43:16): [True: 0, False: 0]
  ------------------
   44|      0|        bytes |= 0xC080;
   45|      0|        s.push_back((bytes >> 8) & 0xFF);
   46|      0|        s.push_back((bytes >> 0) & 0xFF);
   47|      0|        return 2;
   48|      0|    } else if (x < 0x10000) {  // note that 'z' bits must be 0
  ------------------
  |  Branch (48:16): [True: 0, False: 0]
  ------------------
   49|      0|        bytes |= 0xE08080;
   50|      0|        s.push_back((bytes >> 16) & 0xFF);
   51|      0|        s.push_back((bytes >> 8) & 0xFF);
   52|      0|        s.push_back((bytes >> 0) & 0xFF);
   53|      0|        return 3;
   54|      0|    } else if (x < 0x110000) {  // note that capital 'Z' bits must be 0
  ------------------
  |  Branch (54:16): [True: 0, False: 0]
  ------------------
   55|      0|        bytes |= 0xF0808080;
   56|      0|        s.push_back((bytes >> 24) & 0xFF);
   57|      0|        s.push_back((bytes >> 16) & 0xFF);
   58|      0|        s.push_back((bytes >> 8) & 0xFF);
   59|      0|        s.push_back((bytes >> 0) & 0xFF);
   60|      0|        return 4;
   61|      0|    } else {
   62|      0|        std::cerr << "Should never get here." << std::endl;
   63|      0|        abort();
   64|      0|    }
   65|  9.31M|}
vm.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  140|  1.64M|{
  141|  1.64M|    UString r;
  142|  4.41M|    for (size_t i = 0; i < s.length(); ++i)
  ------------------
  |  Branch (142:24): [True: 2.77M, False: 1.64M]
  ------------------
  143|  2.77M|        r.push_back(decode_utf8(s, i));
  144|  1.64M|    return r;
  145|  1.64M|}
vm.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   75|  2.77M|{
   76|  2.77M|    char c0 = str[i];
   77|  2.77M|    if ((c0 & 0x80) == 0) {  // 0xxxxxxx
  ------------------
  |  Branch (77:9): [True: 2.77M, False: 0]
  ------------------
   78|  2.77M|        return c0;
   79|  2.77M|    } else if ((c0 & 0xE0) == 0xC0) {  // 110yyyxx 10xxxxxx
  ------------------
  |  Branch (79:16): [True: 0, False: 0]
  ------------------
   80|      0|        if (i + 1 >= str.length()) {
  ------------------
  |  Branch (80:13): [True: 0, False: 0]
  ------------------
   81|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   82|      0|        }
   83|      0|        char c1 = str[++i];
   84|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (84:13): [True: 0, False: 0]
  ------------------
   85|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   86|      0|        }
   87|      0|        return ((c0 & 0x1F) << 6ul) | (c1 & 0x3F);
   88|      0|    } else if ((c0 & 0xF0) == 0xE0) {  // 1110yyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (88:16): [True: 0, False: 0]
  ------------------
   89|      0|        if (i + 2 >= str.length()) {
  ------------------
  |  Branch (89:13): [True: 0, False: 0]
  ------------------
   90|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   91|      0|        }
   92|      0|        char c1 = str[++i];
   93|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (93:13): [True: 0, False: 0]
  ------------------
   94|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   95|      0|        }
   96|      0|        char c2 = str[++i];
   97|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (97:13): [True: 0, False: 0]
  ------------------
   98|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   99|      0|        }
  100|      0|        return ((c0 & 0xF) << 12ul) | ((c1 & 0x3F) << 6) | (c2 & 0x3F);
  101|      0|    } else if ((c0 & 0xF8) == 0xF0) {  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (101:16): [True: 0, False: 0]
  ------------------
  102|      0|        if (i + 3 >= str.length()) {
  ------------------
  |  Branch (102:13): [True: 0, False: 0]
  ------------------
  103|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  104|      0|        }
  105|      0|        char c1 = str[++i];
  106|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (106:13): [True: 0, False: 0]
  ------------------
  107|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  108|      0|        }
  109|      0|        char c2 = str[++i];
  110|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (110:13): [True: 0, False: 0]
  ------------------
  111|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  112|      0|        }
  113|      0|        char c3 = str[++i];
  114|      0|        if ((c3 & 0xC0) != 0x80) {
  ------------------
  |  Branch (114:13): [True: 0, False: 0]
  ------------------
  115|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  116|      0|        }
  117|      0|        return ((c0 & 0x7) << 24ul) | ((c1 & 0x3F) << 12ul) | ((c2 & 0x3F) << 6) | (c3 & 0x3F);
  118|      0|    } else {
  119|      0|        return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  120|      0|    }
  121|  2.77M|}
vm.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEE:
  133|  1.34M|{
  134|  1.34M|    std::string r;
  135|  1.34M|    encode_utf8(s, r);
  136|  1.34M|    return r;
  137|  1.34M|}
vm.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEERNS2_IcNS3_IcEENS5_IcEEEE:
  127|  1.34M|{
  128|  1.34M|    for (char32_t cp : s)
  ------------------
  |  Branch (128:22): [True: 894M, False: 1.34M]
  ------------------
  129|   894M|        encode_utf8(cp, r);
  130|  1.34M|}
vm.cpp:_ZN7jsonnet8internalL11encode_utf8EDiRNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   33|   894M|{
   34|   894M|    if (x >= JSONNET_CODEPOINT_MAX)
  ------------------
  |  |   22|   894M|#define JSONNET_CODEPOINT_MAX 0x110000
  ------------------
  |  Branch (34:9): [True: 4.61k, False: 894M]
  ------------------
   35|  4.61k|        x = JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  4.61k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   36|       |
   37|       |    // 00ZZZzzz 00zzYYYY 00Yyyyxx 00xxxxxx
   38|   894M|    long bytes = ((x & 0x1C0000) << 6) | ((x & 0x03F000) << 4) | ((x & 0x0FC0) << 2) | (x & 0x3F);
   39|       |
   40|   894M|    if (x < 0x80) {
  ------------------
  |  Branch (40:9): [True: 893M, False: 613k]
  ------------------
   41|   893M|        s.push_back((char)x);
   42|   893M|        return 1;
   43|   893M|    } else if (x < 0x800) {  // note that capital 'Y' bits must be 0
  ------------------
  |  Branch (43:16): [True: 20.2k, False: 593k]
  ------------------
   44|  20.2k|        bytes |= 0xC080;
   45|  20.2k|        s.push_back((bytes >> 8) & 0xFF);
   46|  20.2k|        s.push_back((bytes >> 0) & 0xFF);
   47|  20.2k|        return 2;
   48|   593k|    } else if (x < 0x10000) {  // note that 'z' bits must be 0
  ------------------
  |  Branch (48:16): [True: 592k, False: 311]
  ------------------
   49|   592k|        bytes |= 0xE08080;
   50|   592k|        s.push_back((bytes >> 16) & 0xFF);
   51|   592k|        s.push_back((bytes >> 8) & 0xFF);
   52|   592k|        s.push_back((bytes >> 0) & 0xFF);
   53|   592k|        return 3;
   54|   592k|    } else if (x < 0x110000) {  // note that capital 'Z' bits must be 0
  ------------------
  |  Branch (54:16): [True: 311, False: 0]
  ------------------
   55|    311|        bytes |= 0xF0808080;
   56|    311|        s.push_back((bytes >> 24) & 0xFF);
   57|    311|        s.push_back((bytes >> 16) & 0xFF);
   58|    311|        s.push_back((bytes >> 8) & 0xFF);
   59|    311|        s.push_back((bytes >> 0) & 0xFF);
   60|    311|        return 4;
   61|    311|    } else {
   62|      0|        std::cerr << "Should never get here." << std::endl;
   63|      0|        abort();
   64|      0|    }
   65|   894M|}
_ZN7jsonnet8internal13UStringStreamlsIiEERS1_T_:
  171|  1.65M|    {
  172|  1.65M|        std::stringstream ss;
  173|  1.65M|        ss << c;
  174|  1.65M|        for (char c : ss.str())
  ------------------
  |  Branch (174:21): [True: 4.07M, False: 1.65M]
  ------------------
  175|  4.07M|            buf.push_back(char32_t(c));
  176|  1.65M|        return *this;
  177|  1.65M|    }
_ZN7jsonnet8internal13UStringStreamlsIjEERS1_T_:
  171|   272k|    {
  172|   272k|        std::stringstream ss;
  173|   272k|        ss << c;
  174|   272k|        for (char c : ss.str())
  ------------------
  |  Branch (174:21): [True: 926k, False: 272k]
  ------------------
  175|   926k|            buf.push_back(char32_t(c));
  176|   272k|        return *this;
  177|   272k|    }
desugarer.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEE:
  133|   361k|{
  134|   361k|    std::string r;
  135|   361k|    encode_utf8(s, r);
  136|   361k|    return r;
  137|   361k|}
desugarer.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEERNS2_IcNS3_IcEENS5_IcEEEE:
  127|   361k|{
  128|   361k|    for (char32_t cp : s)
  ------------------
  |  Branch (128:22): [True: 2.37M, False: 361k]
  ------------------
  129|  2.37M|        encode_utf8(cp, r);
  130|   361k|}
desugarer.cpp:_ZN7jsonnet8internalL11encode_utf8EDiRNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   33|  2.37M|{
   34|  2.37M|    if (x >= JSONNET_CODEPOINT_MAX)
  ------------------
  |  |   22|  2.37M|#define JSONNET_CODEPOINT_MAX 0x110000
  ------------------
  |  Branch (34:9): [True: 0, False: 2.37M]
  ------------------
   35|      0|        x = JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   36|       |
   37|       |    // 00ZZZzzz 00zzYYYY 00Yyyyxx 00xxxxxx
   38|  2.37M|    long bytes = ((x & 0x1C0000) << 6) | ((x & 0x03F000) << 4) | ((x & 0x0FC0) << 2) | (x & 0x3F);
   39|       |
   40|  2.37M|    if (x < 0x80) {
  ------------------
  |  Branch (40:9): [True: 2.37M, False: 0]
  ------------------
   41|  2.37M|        s.push_back((char)x);
   42|  2.37M|        return 1;
   43|  2.37M|    } else if (x < 0x800) {  // note that capital 'Y' bits must be 0
  ------------------
  |  Branch (43:16): [True: 0, False: 0]
  ------------------
   44|      0|        bytes |= 0xC080;
   45|      0|        s.push_back((bytes >> 8) & 0xFF);
   46|      0|        s.push_back((bytes >> 0) & 0xFF);
   47|      0|        return 2;
   48|      0|    } else if (x < 0x10000) {  // note that 'z' bits must be 0
  ------------------
  |  Branch (48:16): [True: 0, False: 0]
  ------------------
   49|      0|        bytes |= 0xE08080;
   50|      0|        s.push_back((bytes >> 16) & 0xFF);
   51|      0|        s.push_back((bytes >> 8) & 0xFF);
   52|      0|        s.push_back((bytes >> 0) & 0xFF);
   53|      0|        return 3;
   54|      0|    } else if (x < 0x110000) {  // note that capital 'Z' bits must be 0
  ------------------
  |  Branch (54:16): [True: 0, False: 0]
  ------------------
   55|      0|        bytes |= 0xF0808080;
   56|      0|        s.push_back((bytes >> 24) & 0xFF);
   57|      0|        s.push_back((bytes >> 16) & 0xFF);
   58|      0|        s.push_back((bytes >> 8) & 0xFF);
   59|      0|        s.push_back((bytes >> 0) & 0xFF);
   60|      0|        return 4;
   61|      0|    } else {
   62|      0|        std::cerr << "Should never get here." << std::endl;
   63|      0|        abort();
   64|      0|    }
   65|  2.37M|}
desugarer.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  140|  9.28k|{
  141|  9.28k|    UString r;
  142|  59.2k|    for (size_t i = 0; i < s.length(); ++i)
  ------------------
  |  Branch (142:24): [True: 50.0k, False: 9.28k]
  ------------------
  143|  50.0k|        r.push_back(decode_utf8(s, i));
  144|  9.28k|    return r;
  145|  9.28k|}
desugarer.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   75|  50.0k|{
   76|  50.0k|    char c0 = str[i];
   77|  50.0k|    if ((c0 & 0x80) == 0) {  // 0xxxxxxx
  ------------------
  |  Branch (77:9): [True: 50.0k, False: 0]
  ------------------
   78|  50.0k|        return c0;
   79|  50.0k|    } else if ((c0 & 0xE0) == 0xC0) {  // 110yyyxx 10xxxxxx
  ------------------
  |  Branch (79:16): [True: 0, False: 0]
  ------------------
   80|      0|        if (i + 1 >= str.length()) {
  ------------------
  |  Branch (80:13): [True: 0, False: 0]
  ------------------
   81|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   82|      0|        }
   83|      0|        char c1 = str[++i];
   84|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (84:13): [True: 0, False: 0]
  ------------------
   85|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   86|      0|        }
   87|      0|        return ((c0 & 0x1F) << 6ul) | (c1 & 0x3F);
   88|      0|    } else if ((c0 & 0xF0) == 0xE0) {  // 1110yyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (88:16): [True: 0, False: 0]
  ------------------
   89|      0|        if (i + 2 >= str.length()) {
  ------------------
  |  Branch (89:13): [True: 0, False: 0]
  ------------------
   90|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   91|      0|        }
   92|      0|        char c1 = str[++i];
   93|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (93:13): [True: 0, False: 0]
  ------------------
   94|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   95|      0|        }
   96|      0|        char c2 = str[++i];
   97|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (97:13): [True: 0, False: 0]
  ------------------
   98|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   99|      0|        }
  100|      0|        return ((c0 & 0xF) << 12ul) | ((c1 & 0x3F) << 6) | (c2 & 0x3F);
  101|      0|    } else if ((c0 & 0xF8) == 0xF0) {  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (101:16): [True: 0, False: 0]
  ------------------
  102|      0|        if (i + 3 >= str.length()) {
  ------------------
  |  Branch (102:13): [True: 0, False: 0]
  ------------------
  103|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  104|      0|        }
  105|      0|        char c1 = str[++i];
  106|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (106:13): [True: 0, False: 0]
  ------------------
  107|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  108|      0|        }
  109|      0|        char c2 = str[++i];
  110|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (110:13): [True: 0, False: 0]
  ------------------
  111|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  112|      0|        }
  113|      0|        char c3 = str[++i];
  114|      0|        if ((c3 & 0xC0) != 0x80) {
  ------------------
  |  Branch (114:13): [True: 0, False: 0]
  ------------------
  115|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  116|      0|        }
  117|      0|        return ((c0 & 0x7) << 24ul) | ((c1 & 0x3F) << 12ul) | ((c2 & 0x3F) << 6) | (c3 & 0x3F);
  118|      0|    } else {
  119|      0|        return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  120|      0|    }
  121|  50.0k|}
string_utils.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  140|  21.5M|{
  141|  21.5M|    UString r;
  142|   150M|    for (size_t i = 0; i < s.length(); ++i)
  ------------------
  |  Branch (142:24): [True: 129M, False: 21.5M]
  ------------------
  143|   129M|        r.push_back(decode_utf8(s, i));
  144|  21.5M|    return r;
  145|  21.5M|}
string_utils.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   75|   129M|{
   76|   129M|    char c0 = str[i];
   77|   129M|    if ((c0 & 0x80) == 0) {  // 0xxxxxxx
  ------------------
  |  Branch (77:9): [True: 129M, False: 0]
  ------------------
   78|   129M|        return c0;
   79|   129M|    } else if ((c0 & 0xE0) == 0xC0) {  // 110yyyxx 10xxxxxx
  ------------------
  |  Branch (79:16): [True: 0, False: 0]
  ------------------
   80|      0|        if (i + 1 >= str.length()) {
  ------------------
  |  Branch (80:13): [True: 0, False: 0]
  ------------------
   81|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   82|      0|        }
   83|      0|        char c1 = str[++i];
   84|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (84:13): [True: 0, False: 0]
  ------------------
   85|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   86|      0|        }
   87|      0|        return ((c0 & 0x1F) << 6ul) | (c1 & 0x3F);
   88|      0|    } else if ((c0 & 0xF0) == 0xE0) {  // 1110yyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (88:16): [True: 0, False: 0]
  ------------------
   89|      0|        if (i + 2 >= str.length()) {
  ------------------
  |  Branch (89:13): [True: 0, False: 0]
  ------------------
   90|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   91|      0|        }
   92|      0|        char c1 = str[++i];
   93|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (93:13): [True: 0, False: 0]
  ------------------
   94|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   95|      0|        }
   96|      0|        char c2 = str[++i];
   97|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (97:13): [True: 0, False: 0]
  ------------------
   98|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   99|      0|        }
  100|      0|        return ((c0 & 0xF) << 12ul) | ((c1 & 0x3F) << 6) | (c2 & 0x3F);
  101|      0|    } else if ((c0 & 0xF8) == 0xF0) {  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (101:16): [True: 0, False: 0]
  ------------------
  102|      0|        if (i + 3 >= str.length()) {
  ------------------
  |  Branch (102:13): [True: 0, False: 0]
  ------------------
  103|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  104|      0|        }
  105|      0|        char c1 = str[++i];
  106|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (106:13): [True: 0, False: 0]
  ------------------
  107|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  108|      0|        }
  109|      0|        char c2 = str[++i];
  110|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (110:13): [True: 0, False: 0]
  ------------------
  111|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  112|      0|        }
  113|      0|        char c3 = str[++i];
  114|      0|        if ((c3 & 0xC0) != 0x80) {
  ------------------
  |  Branch (114:13): [True: 0, False: 0]
  ------------------
  115|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  116|      0|        }
  117|      0|        return ((c0 & 0x7) << 24ul) | ((c1 & 0x3F) << 12ul) | ((c2 & 0x3F) << 6) | (c3 & 0x3F);
  118|      0|    } else {
  119|      0|        return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  120|      0|    }
  121|   129M|}
string_utils.cpp:_ZN7jsonnet8internalL11encode_utf8EDiRNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   33|    151|{
   34|    151|    if (x >= JSONNET_CODEPOINT_MAX)
  ------------------
  |  |   22|    151|#define JSONNET_CODEPOINT_MAX 0x110000
  ------------------
  |  Branch (34:9): [True: 6, False: 145]
  ------------------
   35|      6|        x = JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      6|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   36|       |
   37|       |    // 00ZZZzzz 00zzYYYY 00Yyyyxx 00xxxxxx
   38|    151|    long bytes = ((x & 0x1C0000) << 6) | ((x & 0x03F000) << 4) | ((x & 0x0FC0) << 2) | (x & 0x3F);
   39|       |
   40|    151|    if (x < 0x80) {
  ------------------
  |  Branch (40:9): [True: 63, False: 88]
  ------------------
   41|     63|        s.push_back((char)x);
   42|     63|        return 1;
   43|     88|    } else if (x < 0x800) {  // note that capital 'Y' bits must be 0
  ------------------
  |  Branch (43:16): [True: 6, False: 82]
  ------------------
   44|      6|        bytes |= 0xC080;
   45|      6|        s.push_back((bytes >> 8) & 0xFF);
   46|      6|        s.push_back((bytes >> 0) & 0xFF);
   47|      6|        return 2;
   48|     82|    } else if (x < 0x10000) {  // note that 'z' bits must be 0
  ------------------
  |  Branch (48:16): [True: 80, False: 2]
  ------------------
   49|     80|        bytes |= 0xE08080;
   50|     80|        s.push_back((bytes >> 16) & 0xFF);
   51|     80|        s.push_back((bytes >> 8) & 0xFF);
   52|     80|        s.push_back((bytes >> 0) & 0xFF);
   53|     80|        return 3;
   54|     80|    } else if (x < 0x110000) {  // note that capital 'Z' bits must be 0
  ------------------
  |  Branch (54:16): [True: 2, False: 0]
  ------------------
   55|      2|        bytes |= 0xF0808080;
   56|      2|        s.push_back((bytes >> 24) & 0xFF);
   57|      2|        s.push_back((bytes >> 16) & 0xFF);
   58|      2|        s.push_back((bytes >> 8) & 0xFF);
   59|      2|        s.push_back((bytes >> 0) & 0xFF);
   60|      2|        return 4;
   61|      2|    } else {
   62|      0|        std::cerr << "Should never get here." << std::endl;
   63|      0|        abort();
   64|      0|    }
   65|    151|}

_ZN7jsonnet8internal25jsonnet_vm_execute_streamEPNS0_9AllocatorEPKNS0_3ASTERKNSt3__13mapINS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEENS0_5VmExtENS6_4lessISD_EENSB_INS6_4pairIKSD_SE_EEEEEEjddRKNS7_ISD_NS0_16VmNativeCallbackESG_NSB_INSH_ISI_SO_EEEEEEPFiPvPKcSW_PPcSY_PmESU_b:
 3375|  4.16k|{
 3376|  4.16k|    Interpreter vm(alloc,
 3377|  4.16k|                   ext_vars,
 3378|  4.16k|                   max_stack,
 3379|  4.16k|                   gc_min_objects,
 3380|  4.16k|                   gc_growth_trigger,
 3381|  4.16k|                   natives,
 3382|  4.16k|                   import_callback,
 3383|  4.16k|                   ctx);
 3384|  4.16k|    vm.evaluate(ast, 0);
 3385|  4.16k|    return vm.manifestStream(string_output);
 3386|  4.16k|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111InterpreterC2EPNS0_9AllocatorERKNSt3__13mapINS5_12basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEENS0_5VmExtENS5_4lessISC_EENSA_INS5_4pairIKSC_SD_EEEEEEjddRKNS6_ISC_NS0_16VmNativeCallbackESF_NSA_INSG_ISH_SN_EEEEEEPFiPvPKcSV_PPcSX_PmEST_:
  902|  4.16k|    {
  903|  4.16k|        scratch = makeNull();
  904|  4.16k|        builtins["makeArray"] = &Interpreter::builtinMakeArray;
  905|  4.16k|        builtins["pow"] = &Interpreter::builtinPow;
  906|  4.16k|        builtins["floor"] = &Interpreter::builtinFloor;
  907|  4.16k|        builtins["ceil"] = &Interpreter::builtinCeil;
  908|  4.16k|        builtins["sqrt"] = &Interpreter::builtinSqrt;
  909|  4.16k|        builtins["sin"] = &Interpreter::builtinSin;
  910|  4.16k|        builtins["cos"] = &Interpreter::builtinCos;
  911|  4.16k|        builtins["tan"] = &Interpreter::builtinTan;
  912|  4.16k|        builtins["asin"] = &Interpreter::builtinAsin;
  913|  4.16k|        builtins["acos"] = &Interpreter::builtinAcos;
  914|  4.16k|        builtins["atan"] = &Interpreter::builtinAtan;
  915|  4.16k|        builtins["type"] = &Interpreter::builtinType;
  916|  4.16k|        builtins["filter"] = &Interpreter::builtinFilter;
  917|  4.16k|        builtins["objectHasEx"] = &Interpreter::builtinObjectHasEx;
  918|  4.16k|        builtins["length"] = &Interpreter::builtinLength;
  919|  4.16k|        builtins["objectFieldsEx"] = &Interpreter::builtinObjectFieldsEx;
  920|  4.16k|        builtins["codepoint"] = &Interpreter::builtinCodepoint;
  921|  4.16k|        builtins["char"] = &Interpreter::builtinChar;
  922|  4.16k|        builtins["log"] = &Interpreter::builtinLog;
  923|  4.16k|        builtins["exp"] = &Interpreter::builtinExp;
  924|  4.16k|        builtins["mantissa"] = &Interpreter::builtinMantissa;
  925|  4.16k|        builtins["exponent"] = &Interpreter::builtinExponent;
  926|  4.16k|        builtins["modulo"] = &Interpreter::builtinModulo;
  927|  4.16k|        builtins["extVar"] = &Interpreter::builtinExtVar;
  928|  4.16k|        builtins["primitiveEquals"] = &Interpreter::builtinPrimitiveEquals;
  929|  4.16k|        builtins["native"] = &Interpreter::builtinNative;
  930|  4.16k|        builtins["md5"] = &Interpreter::builtinMd5;
  931|  4.16k|        builtins["trace"] = &Interpreter::builtinTrace;
  932|  4.16k|        builtins["splitLimit"] = &Interpreter::builtinSplitLimit;
  933|  4.16k|        builtins["substr"] = &Interpreter::builtinSubstr;
  934|  4.16k|        builtins["range"] = &Interpreter::builtinRange;
  935|  4.16k|        builtins["strReplace"] = &Interpreter::builtinStrReplace;
  936|  4.16k|        builtins["asciiLower"] = &Interpreter::builtinAsciiLower;
  937|  4.16k|        builtins["asciiUpper"] = &Interpreter::builtinAsciiUpper;
  938|  4.16k|        builtins["join"] = &Interpreter::builtinJoin;
  939|  4.16k|        builtins["parseJson"] = &Interpreter::builtinParseJson;
  940|  4.16k|        builtins["parseYaml"] = &Interpreter::builtinParseYaml;
  941|  4.16k|        builtins["encodeUTF8"] = &Interpreter::builtinEncodeUTF8;
  942|  4.16k|        builtins["decodeUTF8"] = &Interpreter::builtinDecodeUTF8;
  943|       |
  944|  4.16k|        DesugaredObject *stdlib = makeStdlibAST(alloc, "__internal__");
  945|  4.16k|        jsonnet_static_analysis(stdlib);
  946|  4.16k|        stdlibAST = stdlib; // stdlibAST is const, so we need to do analysis before this assignment
  947|  4.16k|        auto stdThunk = makeHeap<HeapThunk>(nullptr, nullptr, 0, static_cast<const AST*>(stdlibAST));
  948|  4.16k|        stack.newCall(stdThunk->body->location, stdThunk, stdThunk->self, stdThunk->offset, stdThunk->upValues);
  949|  4.16k|        evaluate(stdThunk->body, 0);
  950|  4.16k|        stdObject = dynamic_cast<HeapObject*>(scratch.v.h);
  951|  4.16k|        prepareSourceValThunks();
  952|  4.16k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15StackC2Ej:
  248|  4.16k|    Stack(unsigned limit) : calls(0), limit(limit) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeNullEv:
  624|  92.4k|    {
  625|  92.4k|        Value r;
  626|  92.4k|        r.t = Value::NULL_TYPE;
  627|  92.4k|        return r;
  628|  92.4k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack3topEv:
  281|   448M|    {
  282|   448M|        return stack.back();
  283|   448M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter19validateBuiltinArgsERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEERKNS6_6vectorINS1_5ValueENSA_ISG_EEEENSF_INSG_4TypeENSA_ISL_EEEE:
  976|   229k|    {
  977|   229k|        if (args.size() == params.size()) {
  ------------------
  |  Branch (977:13): [True: 229k, False: 0]
  ------------------
  978|   671k|            for (std::size_t i = 0; i < args.size(); ++i) {
  ------------------
  |  Branch (978:37): [True: 442k, False: 229k]
  ------------------
  979|   442k|                if (args[i].t != params[i])
  ------------------
  |  Branch (979:21): [True: 0, False: 442k]
  ------------------
  980|      0|                    goto bad;
  981|   442k|            }
  982|   229k|            return;
  983|   229k|        }
  984|      0|    bad:;
  985|      0|        std::stringstream ss;
  986|      0|        ss << "Builtin function " + name + " expected (";
  987|      0|        const char *prefix = "";
  988|      0|        for (auto p : params) {
  ------------------
  |  Branch (988:21): [True: 0, False: 0]
  ------------------
  989|      0|            ss << prefix << type_str(p);
  990|      0|            prefix = ", ";
  991|      0|        }
  992|      0|        ss << ") but got (";
  993|      0|        prefix = "";
  994|      0|        for (auto a : args) {
  ------------------
  |  Branch (994:21): [True: 0, False: 0]
  ------------------
  995|      0|            ss << prefix << type_str(a);
  996|      0|            prefix = ", ";
  997|      0|        }
  998|      0|        ss << ")";
  999|      0|        throw makeError(loc, ss.str());
 1000|   229k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter9makeErrorERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  557|  2.81k|    {
  558|  2.81k|        return stack.makeError(loc, msg);
  559|  2.81k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack9makeErrorERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  358|  3.45k|    {
  359|  3.45k|        std::vector<TraceFrame> stack_trace;
  360|  3.45k|        stack_trace.push_back(TraceFrame(loc));
  361|   938k|        for (int i = stack.size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (361:40): [True: 935k, False: 3.45k]
  ------------------
  362|   935k|            const auto &f = stack[i];
  363|   935k|            if (f.isCall()) {
  ------------------
  |  Branch (363:17): [True: 337k, False: 597k]
  ------------------
  364|   337k|                if (f.context != nullptr) {
  ------------------
  |  Branch (364:21): [True: 337k, False: 0]
  ------------------
  365|       |                    // Give the last line a name.
  366|   337k|                    stack_trace[stack_trace.size() - 1].name = getName(i, f.context);
  367|   337k|                }
  368|   337k|                if (f.location.isSet() || f.location.file.length() > 0)
  ------------------
  |  Branch (368:21): [True: 263k, False: 73.7k]
  |  Branch (368:43): [True: 127, False: 73.6k]
  ------------------
  369|   263k|                    stack_trace.push_back(TraceFrame(f.location));
  370|   337k|            }
  371|   935k|        }
  372|  3.45k|        return RuntimeError(stack_trace, msg);
  373|  3.45k|    }
vm.cpp:_ZNK7jsonnet8internal12_GLOBAL__N_15Frame6isCallEv:
  231|   256M|    {
  232|   256M|        return kind == FRAME_CALL;
  233|   256M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack7getNameEjPKNS1_10HeapEntityE:
  303|   337k|    {
  304|   337k|        std::string name;
  305|   927k|        for (int i = from_here - 1; i >= 0; --i) {
  ------------------
  |  Branch (305:37): [True: 925k, False: 1.97k]
  ------------------
  306|   925k|            const auto &f = stack[i];
  307|   925k|            for (const auto &pair : f.bindings) {
  ------------------
  |  Branch (307:35): [True: 408k, False: 925k]
  ------------------
  308|   408k|                HeapThunk *thunk = pair.second;
  309|   408k|                if (!thunk->filled)
  ------------------
  |  Branch (309:21): [True: 86.8k, False: 321k]
  ------------------
  310|  86.8k|                    continue;
  311|   321k|                if (!thunk->content.isHeap())
  ------------------
  |  Branch (311:21): [True: 51.4k, False: 270k]
  ------------------
  312|  51.4k|                    continue;
  313|   270k|                if (e != thunk->content.v.h)
  ------------------
  |  Branch (313:21): [True: 229k, False: 41.0k]
  ------------------
  314|   229k|                    continue;
  315|  41.0k|                name = encode_utf8(pair.first->name);
  316|  41.0k|            }
  317|       |            // Do not go into the next call frame, keep local reasoning.
  318|   925k|            if (f.isCall())
  ------------------
  |  Branch (318:17): [True: 335k, False: 589k]
  ------------------
  319|   335k|                break;
  320|   925k|        }
  321|       |
  322|   337k|        if (name == "")
  ------------------
  |  Branch (322:13): [True: 296k, False: 41.0k]
  ------------------
  323|   296k|            name = "anonymous";
  324|   337k|        if (dynamic_cast<const HeapObject *>(e)) {
  ------------------
  |  Branch (324:13): [True: 245k, False: 91.5k]
  ------------------
  325|   245k|            return "object <" + name + ">";
  326|   245k|        } else if (auto *thunk = dynamic_cast<const HeapThunk *>(e)) {
  ------------------
  |  Branch (326:26): [True: 47.9k, False: 43.6k]
  ------------------
  327|  47.9k|            if (thunk->name == nullptr) {
  ------------------
  |  Branch (327:17): [True: 7.82k, False: 40.0k]
  ------------------
  328|  7.82k|                return "";  // Argument of builtin, or root (since top level functions).
  329|  40.0k|            } else {
  330|  40.0k|                return "thunk <" + encode_utf8(thunk->name->name) + ">";
  331|  40.0k|            }
  332|  47.9k|        } else {
  333|  43.6k|            const auto *func = static_cast<const HeapClosure *>(e);
  334|  43.6k|            if (func->body == nullptr) {
  ------------------
  |  Branch (334:17): [True: 0, False: 43.6k]
  ------------------
  335|      0|                return "builtin function <" + func->builtinName + ">";
  336|      0|            }
  337|  43.6k|            return "function <" + name + ">";
  338|  43.6k|        }
  339|   337k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack4markERNS1_4HeapE:
  274|  87.5k|    {
  275|  19.8M|        for (const auto &f : stack) {
  ------------------
  |  Branch (275:28): [True: 19.8M, False: 87.5k]
  ------------------
  276|  19.8M|            f.mark(heap);
  277|  19.8M|        }
  278|  87.5k|    }
vm.cpp:_ZNK7jsonnet8internal12_GLOBAL__N_15Frame4markERNS1_4HeapE:
  215|  19.8M|    {
  216|  19.8M|        heap.markFrom(val);
  217|  19.8M|        heap.markFrom(val2);
  218|  19.8M|        if (context)
  ------------------
  |  Branch (218:13): [True: 13.1M, False: 6.72M]
  ------------------
  219|  13.1M|            heap.markFrom(context);
  220|  19.8M|        if (self)
  ------------------
  |  Branch (220:13): [True: 12.8M, False: 6.99M]
  ------------------
  221|  12.8M|            heap.markFrom(self);
  222|  19.8M|        for (const auto &bind : bindings)
  ------------------
  |  Branch (222:31): [True: 14.3M, False: 19.8M]
  ------------------
  223|  14.3M|            heap.markFrom(bind.second);
  224|  19.8M|        for (const auto &el : elements)
  ------------------
  |  Branch (224:29): [True: 0, False: 19.8M]
  ------------------
  225|      0|            heap.markFrom(el.second);
  226|  19.8M|        for (const auto &th : thunks)
  ------------------
  |  Branch (226:29): [True: 979k, False: 19.8M]
  ------------------
  227|   979k|            heap.markFrom(th);
  228|  19.8M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10makeNumberEd:
  605|  3.21M|    {
  606|  3.21M|        Value r;
  607|  3.21M|        r.t = Value::NUMBER;
  608|  3.21M|        r.v.d = v;
  609|  3.21M|        return r;
  610|  3.21M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter9makeArrayERKNSt3__16vectorIPNS1_9HeapThunkENS3_9allocatorIS6_EEEE:
  631|  1.11M|    {
  632|  1.11M|        Value r;
  633|  1.11M|        r.t = Value::ARRAY;
  634|  1.11M|        r.v.h = makeHeap<HeapArray>(v);
  635|  1.11M|        return r;
  636|  1.11M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapArrayEJRKNSt3__16vectorIPNS1_9HeapThunkENS5_9allocatorIS8_EEEEEEEPT_DpOT0_:
  567|  1.11M|    {
  568|  1.11M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|  1.11M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 1.51k, False: 1.11M]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|  1.51k|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|  1.51k|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|  1.51k|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|  1.51k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 1.51k]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|   231k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 231k, False: 1.51k]
  ------------------
  587|   231k|                heap.markFrom(sourceVal.second);
  588|   231k|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|  1.51k|            heap.sweep();
  592|  1.51k|        }
  593|  1.11M|        return r;
  594|  1.11M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10builtinPowERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1036|  1.60k|    {
 1037|  1.60k|        validateBuiltinArgs(loc, "pow", args, {Value::NUMBER, Value::NUMBER});
 1038|  1.60k|        scratch = makeNumberCheck(loc, std::pow(args[0].v.d, args[1].v.d));
 1039|  1.60k|        return nullptr;
 1040|  1.60k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter15makeNumberCheckERKNS0_13LocationRangeEd:
  613|  2.70M|    {
  614|  2.70M|        if (std::isnan(v)) {
  ------------------
  |  Branch (614:13): [True: 0, False: 2.70M]
  ------------------
  615|      0|            throw makeError(loc, "not a number");
  616|      0|        }
  617|  2.70M|        if (std::isinf(v)) {
  ------------------
  |  Branch (617:13): [True: 22, False: 2.70M]
  ------------------
  618|     22|            throw makeError(loc, "overflow");
  619|     22|        }
  620|  2.70M|        return makeNumber(v);
  621|  2.70M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter12builtinFloorERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1043|  14.6k|    {
 1044|  14.6k|        validateBuiltinArgs(loc, "floor", args, {Value::NUMBER});
 1045|  14.6k|        scratch = makeNumberCheck(loc, std::floor(args[0].v.d));
 1046|  14.6k|        return nullptr;
 1047|  14.6k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11builtinTypeERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1106|  2.33M|    {
 1107|  2.33M|        switch (args[0].t) {
  ------------------
  |  Branch (1107:17): [True: 0, False: 2.33M]
  ------------------
 1108|   123k|            case Value::NULL_TYPE: scratch = makeString(U"null"); return nullptr;
  ------------------
  |  Branch (1108:13): [True: 123k, False: 2.21M]
  ------------------
 1109|       |
 1110|   135k|            case Value::BOOLEAN: scratch = makeString(U"boolean"); return nullptr;
  ------------------
  |  Branch (1110:13): [True: 135k, False: 2.20M]
  ------------------
 1111|       |
 1112|   336k|            case Value::NUMBER: scratch = makeString(U"number"); return nullptr;
  ------------------
  |  Branch (1112:13): [True: 336k, False: 2.00M]
  ------------------
 1113|       |
 1114|   137k|            case Value::ARRAY: scratch = makeString(U"array"); return nullptr;
  ------------------
  |  Branch (1114:13): [True: 137k, False: 2.19M]
  ------------------
 1115|       |
 1116|    530|            case Value::FUNCTION: scratch = makeString(U"function"); return nullptr;
  ------------------
  |  Branch (1116:13): [True: 530, False: 2.33M]
  ------------------
 1117|       |
 1118|   130k|            case Value::OBJECT: scratch = makeString(U"object"); return nullptr;
  ------------------
  |  Branch (1118:13): [True: 130k, False: 2.20M]
  ------------------
 1119|       |
 1120|  1.47M|            case Value::STRING: scratch = makeString(U"string"); return nullptr;
  ------------------
  |  Branch (1120:13): [True: 1.47M, False: 864k]
  ------------------
 1121|  2.33M|        }
 1122|      0|        return nullptr;  // Quiet, compiler.
 1123|  2.33M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10makeStringERKNSt3__112basic_stringIDiNS3_11char_traitsIDiEENS3_9allocatorIDiEEEE:
  675|  31.6M|    {
  676|  31.6M|        Value r;
  677|  31.6M|        r.t = Value::STRING;
  678|  31.6M|        r.v.h = makeHeap<HeapString>(v);
  679|  31.6M|        return r;
  680|  31.6M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_10HeapStringEJRKNSt3__112basic_stringIDiNS5_11char_traitsIDiEENS5_9allocatorIDiEEEEEEEPT_DpOT0_:
  567|  31.6M|    {
  568|  31.6M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|  31.6M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 35.4k, False: 31.5M]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|  35.4k|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|  35.4k|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|  35.4k|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|  35.4k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 35.4k]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|  5.42M|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 5.42M, False: 35.4k]
  ------------------
  587|  5.42M|                heap.markFrom(sourceVal.second);
  588|  5.42M|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|  35.4k|            heap.sweep();
  592|  35.4k|        }
  593|  31.6M|        return r;
  594|  31.6M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter12objectFieldsEPKNS1_10HeapObjectEb:
  756|   750k|    {
  757|   750k|        std::set<const Identifier *> r;
  758|   772k|        for (const auto &pair : objectFieldsAux(obj_)) {
  ------------------
  |  Branch (758:31): [True: 772k, False: 750k]
  ------------------
  759|   772k|            if (!manifesting || pair.second != ObjectField::HIDDEN)
  ------------------
  |  Branch (759:17): [True: 0, False: 772k]
  |  Branch (759:33): [True: 767k, False: 5.10k]
  ------------------
  760|   767k|                r.insert(pair.first);
  761|   772k|        }
  762|   750k|        return r;
  763|   750k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter15objectFieldsAuxEPKNS1_10HeapObjectE:
  726|  32.6M|    {
  727|  32.6M|        IdHideMap r;
  728|  32.6M|        if (auto *obj = dynamic_cast<const HeapSimpleObject *>(obj_)) {
  ------------------
  |  Branch (728:19): [True: 16.6M, False: 15.9M]
  ------------------
  729|  16.6M|            for (const auto &f : obj->fields) {
  ------------------
  |  Branch (729:32): [True: 6.07M, False: 16.6M]
  ------------------
  730|  6.07M|                r[f.first] = f.second.hide;
  731|  6.07M|            }
  732|       |
  733|  16.6M|        } else if (auto *obj = dynamic_cast<const HeapExtendedObject *>(obj_)) {
  ------------------
  |  Branch (733:26): [True: 15.9M, False: 0]
  ------------------
  734|  15.9M|            r = objectFieldsAux(obj->right);
  735|  28.0M|            for (const auto &pair : objectFieldsAux(obj->left)) {
  ------------------
  |  Branch (735:35): [True: 28.0M, False: 15.9M]
  ------------------
  736|  28.0M|                auto it = r.find(pair.first);
  737|  28.0M|                if (it == r.end()) {
  ------------------
  |  Branch (737:21): [True: 22.7M, False: 5.30M]
  ------------------
  738|       |                    // First time it is seen
  739|  22.7M|                    r[pair.first] = pair.second;
  740|  22.7M|                } else if (it->second == ObjectField::INHERIT) {
  ------------------
  |  Branch (740:28): [True: 5.05M, False: 250k]
  ------------------
  741|       |                    // Seen before, but with inherited visibility so use new visibility
  742|  5.05M|                    r[pair.first] = pair.second;
  743|  5.05M|                }
  744|  28.0M|            }
  745|       |
  746|  15.9M|        } else if (auto *obj = dynamic_cast<const HeapComprehensionObject *>(obj_)) {
  ------------------
  |  Branch (746:26): [True: 0, False: 0]
  ------------------
  747|      0|            for (const auto &f : obj->compValues)
  ------------------
  |  Branch (747:32): [True: 0, False: 0]
  ------------------
  748|      0|                r[f.first] = ObjectField::VISIBLE;
  749|      0|        }
  750|  32.6M|        return r;
  751|  32.6M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11makeBooleanEb:
  597|  8.37M|    {
  598|  8.37M|        Value r;
  599|  8.37M|        r.t = Value::BOOLEAN;
  600|  8.37M|        r.v.b = v;
  601|  8.37M|        return r;
  602|  8.37M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13builtinLengthERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1171|   470k|    {
 1172|   470k|        if (args.size() != 1) {
  ------------------
  |  Branch (1172:13): [True: 0, False: 470k]
  ------------------
 1173|      0|            throw makeError(loc, "length takes 1 parameter.");
 1174|      0|        }
 1175|   470k|        HeapEntity *e = args[0].v.h;
 1176|   470k|        switch (args[0].t) {
 1177|      7|            case Value::OBJECT: {
  ------------------
  |  Branch (1177:13): [True: 7, False: 470k]
  ------------------
 1178|      7|                auto fields = objectFields(static_cast<HeapObject *>(e), true);
 1179|      7|                scratch = makeNumber(fields.size());
 1180|      7|            } break;
 1181|       |
 1182|   241k|            case Value::ARRAY:
  ------------------
  |  Branch (1182:13): [True: 241k, False: 229k]
  ------------------
 1183|   241k|                scratch = makeNumber(static_cast<HeapArray *>(e)->elements.size());
 1184|   241k|                break;
 1185|       |
 1186|   229k|            case Value::STRING:
  ------------------
  |  Branch (1186:13): [True: 229k, False: 241k]
  ------------------
 1187|   229k|                scratch = makeNumber(static_cast<HeapString *>(e)->value.length());
 1188|   229k|                break;
 1189|       |
 1190|      0|            case Value::FUNCTION:
  ------------------
  |  Branch (1190:13): [True: 0, False: 470k]
  ------------------
 1191|      0|                scratch = makeNumber(static_cast<HeapClosure *>(e)->params.size());
 1192|      0|                break;
 1193|       |
 1194|     26|            default:
  ------------------
  |  Branch (1194:13): [True: 26, False: 470k]
  ------------------
 1195|     26|                throw makeError(loc,
 1196|     26|                                "length operates on strings, objects, "
 1197|     26|                                "and arrays, got " +
 1198|     26|                                    type_str(args[0]));
 1199|   470k|        }
 1200|   470k|        return nullptr;
 1201|   470k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter21builtinObjectFieldsExERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1204|   117k|    {
 1205|   117k|        validateBuiltinArgs(loc, "objectFieldsEx", args, {Value::OBJECT, Value::BOOLEAN});
 1206|   117k|        const auto *obj = static_cast<HeapObject *>(args[0].v.h);
 1207|   117k|        bool include_hidden = args[1].v.b;
 1208|       |        // Stash in a set first to sort them.
 1209|   117k|        std::set<UString> fields;
 1210|   117k|        for (const auto &field : objectFields(obj, !include_hidden)) {
  ------------------
  |  Branch (1210:32): [True: 104k, False: 117k]
  ------------------
 1211|   104k|            fields.insert(field->name);
 1212|   104k|        }
 1213|   117k|        scratch = makeArray({});
 1214|   117k|        auto &elements = static_cast<HeapArray *>(scratch.v.h)->elements;
 1215|   117k|        for (const auto &field : fields) {
  ------------------
  |  Branch (1215:32): [True: 104k, False: 117k]
  ------------------
 1216|   104k|            auto *th = makeHeap<HeapThunk>(idArrayElement, nullptr, 0, nullptr);
 1217|   104k|            elements.push_back(th);
 1218|   104k|            th->fill(makeString(field));
 1219|   104k|        }
 1220|   117k|        return nullptr;
 1221|   117k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJRPKNS0_10IdentifierEDniDnEEEPT_DpOT0_:
  567|   104k|    {
  568|   104k|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|   104k|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 39, False: 104k]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|     39|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|     39|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|     39|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|     39|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 39]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|  5.96k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 5.96k, False: 39]
  ------------------
  587|  5.96k|                heap.markFrom(sourceVal.second);
  588|  5.96k|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|     39|            heap.sweep();
  592|     39|        }
  593|   104k|        return r;
  594|   104k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11builtinCharERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1238|    393|    {
 1239|    393|        validateBuiltinArgs(loc, "char", args, {Value::NUMBER});
 1240|    393|        long l = long(args[0].v.d);
 1241|    393|        if (l < 0) {
  ------------------
  |  Branch (1241:13): [True: 72, False: 321]
  ------------------
 1242|     72|            std::stringstream ss;
 1243|     72|            ss << "codepoints must be >= 0, got " << l;
 1244|     72|            throw makeError(loc, ss.str());
 1245|     72|        }
 1246|    321|        if (l >= JSONNET_CODEPOINT_MAX) {
  ------------------
  |  |   22|    321|#define JSONNET_CODEPOINT_MAX 0x110000
  ------------------
  |  Branch (1246:13): [True: 46, False: 275]
  ------------------
 1247|     46|            std::stringstream ss;
 1248|     46|            ss << "invalid unicode codepoint, got " << l;
 1249|     46|            throw makeError(loc, ss.str());
 1250|     46|        }
 1251|    275|        char32_t c = l;
 1252|    275|        scratch = makeString(UString(&c, 1));
 1253|    275|        return nullptr;
 1254|    321|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10builtinLogERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1257|  2.63k|    {
 1258|  2.63k|        validateBuiltinArgs(loc, "log", args, {Value::NUMBER});
 1259|  2.63k|        scratch = makeNumberCheck(loc, std::log(args[0].v.d));
 1260|  2.63k|        return nullptr;
 1261|  2.63k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13builtinModuloERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1289|  91.6k|    {
 1290|  91.6k|        validateBuiltinArgs(loc, "modulo", args, {Value::NUMBER, Value::NUMBER});
 1291|  91.6k|        double a = args[0].v.d;
 1292|  91.6k|        double b = args[1].v.d;
 1293|  91.6k|        if (b == 0)
  ------------------
  |  Branch (1293:13): [True: 9, False: 91.6k]
  ------------------
 1294|      9|            throw makeError(loc, "division by zero.");
 1295|  91.6k|        scratch = makeNumberCheck(loc, std::fmod(a, b));
 1296|  91.6k|        return nullptr;
 1297|  91.6k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack3popEv:
  291|  87.0M|    {
  292|  87.0M|        if (top().isCall())
  ------------------
  |  Branch (292:13): [True: 33.1M, False: 53.9M]
  ------------------
  293|  33.1M|            calls--;
  294|  87.0M|        stack.pop_back();
  295|  87.0M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter22builtinPrimitiveEqualsERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1325|  3.66M|    {
 1326|  3.66M|        if (args.size() != 2) {
  ------------------
  |  Branch (1326:13): [True: 0, False: 3.66M]
  ------------------
 1327|      0|            std::stringstream ss;
 1328|      0|            ss << "primitiveEquals takes 2 parameters, got " << args.size();
 1329|      0|            throw makeError(loc, ss.str());
 1330|      0|        }
 1331|  3.66M|        if (args[0].t != args[1].t) {
  ------------------
  |  Branch (1331:13): [True: 0, False: 3.66M]
  ------------------
 1332|      0|            scratch = makeBoolean(false);
 1333|      0|            return nullptr;
 1334|      0|        }
 1335|  3.66M|        bool r;
 1336|  3.66M|        switch (args[0].t) {
 1337|  40.7k|            case Value::BOOLEAN: r = args[0].v.b == args[1].v.b; break;
  ------------------
  |  Branch (1337:13): [True: 40.7k, False: 3.62M]
  ------------------
 1338|       |
 1339|  86.9k|            case Value::NUMBER: r = args[0].v.d == args[1].v.d; break;
  ------------------
  |  Branch (1339:13): [True: 86.9k, False: 3.57M]
  ------------------
 1340|       |
 1341|  3.49M|            case Value::STRING:
  ------------------
  |  Branch (1341:13): [True: 3.49M, False: 169k]
  ------------------
 1342|  3.49M|                r = static_cast<HeapString *>(args[0].v.h)->value ==
 1343|  3.49M|                    static_cast<HeapString *>(args[1].v.h)->value;
 1344|  3.49M|                break;
 1345|       |
 1346|  41.3k|            case Value::NULL_TYPE: r = true; break;
  ------------------
  |  Branch (1346:13): [True: 41.3k, False: 3.62M]
  ------------------
 1347|       |
 1348|      8|            case Value::FUNCTION: throw makeError(loc, "cannot test equality of functions"); break;
  ------------------
  |  Branch (1348:13): [True: 8, False: 3.66M]
  ------------------
 1349|       |
 1350|      0|            default:
  ------------------
  |  Branch (1350:13): [True: 0, False: 3.66M]
  ------------------
 1351|      0|                throw makeError(loc,
 1352|      0|                                "primitiveEquals operates on primitive "
 1353|      0|                                "types, got " +
 1354|      0|                                    type_str(args[0]));
 1355|  3.66M|        }
 1356|  3.66M|        scratch = makeBoolean(r);
 1357|  3.66M|        return nullptr;
 1358|  3.66M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11makeBuiltinERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERKNS3_6vectorINS1_11HeapClosure5ParamENS7_ISE_EEEE:
  657|  6.71M|    {
  658|  6.71M|        AST *body = nullptr;
  659|  6.71M|        Value r;
  660|  6.71M|        r.t = Value::FUNCTION;
  661|  6.71M|        r.v.h = makeHeap<HeapClosure>(BindingFrame(), nullptr, 0, params, body, name);
  662|  6.71M|        return r;
  663|  6.71M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_11HeapClosureEJNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEEDniRKNS5_6vectorINS4_5ParamENSE_ISL_EEEERPNS0_3ASTERKNS5_12basic_stringIcNS5_11char_traitsIcEENSE_IcEEEEEEEPT_DpOT0_:
  567|  6.71M|    {
  568|  6.71M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|  6.71M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 8.03k, False: 6.70M]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|  8.03k|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|  8.03k|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|  8.03k|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|  8.03k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 8.03k]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|  1.22M|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 1.22M, False: 8.03k]
  ------------------
  587|  1.22M|                heap.markFrom(sourceVal.second);
  588|  1.22M|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|  8.03k|            heap.sweep();
  592|  8.03k|        }
  593|  6.71M|        return r;
  594|  6.71M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13builtinSubstrERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1492|    686|    {
 1493|    686|        validateBuiltinArgs(loc, "substr", args, {Value::STRING, Value::NUMBER, Value::NUMBER});
 1494|    686|        const auto *str = static_cast<const HeapString *>(args[0].v.h);
 1495|    686|        long from = long(args[1].v.d);
 1496|    686|        long len = long(args[2].v.d);
 1497|    686|        if (from < 0) {
  ------------------
  |  Branch (1497:13): [True: 0, False: 686]
  ------------------
 1498|      0|            std::stringstream ss;
 1499|      0|            ss << "substr second parameter should be greater than zero, got " << from;
 1500|      0|            throw makeError(loc, ss.str());
 1501|      0|        }
 1502|    686|        if (len < 0) {
  ------------------
  |  Branch (1502:13): [True: 0, False: 686]
  ------------------
 1503|      0|            std::stringstream ss;
 1504|      0|            ss << "substr third parameter should be greater than zero, got " << len;
 1505|      0|            throw makeError(loc, ss.str());
 1506|      0|        }
 1507|    686|        if (static_cast<unsigned long>(from) > str->value.size()) {
  ------------------
  |  Branch (1507:13): [True: 0, False: 686]
  ------------------
 1508|      0|            scratch = makeString(UString());
 1509|      0|            return nullptr;
 1510|      0|        }
 1511|    686|        if (size_t(len + from) > str->value.size()) {
  ------------------
  |  Branch (1511:13): [True: 0, False: 686]
  ------------------
 1512|      0|          len = str->value.size() - from;
 1513|      0|        }
 1514|    686|        scratch = makeString(str->value.substr(from, len));
 1515|    686|        return nullptr;
 1516|    686|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJDnDniPKNS0_3ASTEEEEPT_DpOT0_:
  567|  4.16k|    {
  568|  4.16k|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|  4.16k|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 0, False: 4.16k]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|      0|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|      0|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|      0|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|      0|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 0]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|      0|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 0, False: 0]
  ------------------
  587|      0|                heap.markFrom(sourceVal.second);
  588|      0|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|      0|            heap.sweep();
  592|      0|        }
  593|  4.16k|        return r;
  594|  4.16k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack7newCallERKNS0_13LocationRangeEPNS1_10HeapEntityEPNS1_10HeapObjectEjRKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENSA_4lessISE_EENSA_9allocatorINSA_4pairIKSE_SG_EEEEEE:
  408|  33.8M|    {
  409|  33.8M|        tailCallTrimStack();
  410|  33.8M|        if (calls >= limit) {
  ------------------
  |  Branch (410:13): [True: 635, False: 33.8M]
  ------------------
  411|    635|            throw makeError(loc, "max stack frames exceeded.");
  412|    635|        }
  413|  33.8M|        stack.emplace_back(FRAME_CALL, loc);
  414|  33.8M|        calls++;
  415|  33.8M|        top().context = context;
  416|  33.8M|        top().self = self;
  417|  33.8M|        top().offset = offset;
  418|  33.8M|        top().bindings = up_values;
  419|  33.8M|        top().tailCall = false;
  420|       |
  421|  33.8M|#ifndef NDEBUG
  422|  33.8M|        for (const auto &bind : up_values) {
  ------------------
  |  Branch (422:31): [True: 26.6M, False: 33.8M]
  ------------------
  423|  26.6M|            if (bind.second == nullptr) {
  ------------------
  |  Branch (423:17): [True: 0, False: 26.6M]
  ------------------
  424|      0|                std::cerr << "INTERNAL ERROR: No binding for variable "
  425|      0|                          << encode_utf8(bind.first->name) << std::endl;
  426|      0|                std::abort();
  427|      0|            }
  428|  26.6M|        }
  429|  33.8M|#endif
  430|  33.8M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack17tailCallTrimStackEv:
  384|  33.8M|    {
  385|  34.7M|        for (int i = stack.size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (385:40): [True: 34.1M, False: 624k]
  ------------------
  386|  34.1M|            switch (stack[i].kind) {
  387|  8.86M|                case FRAME_CALL: {
  ------------------
  |  Branch (387:17): [True: 8.86M, False: 25.2M]
  ------------------
  388|  8.86M|                    if (!stack[i].tailCall || stack[i].thunks.size() > 0) {
  ------------------
  |  Branch (388:25): [True: 5.66M, False: 3.20M]
  |  Branch (388:47): [True: 2.86M, False: 332k]
  ------------------
  389|  8.53M|                        return;
  390|  8.53M|                    }
  391|       |                    // Remove all stack frames including this one.
  392|  1.34M|                    while (stack.size() > unsigned(i))
  ------------------
  |  Branch (392:28): [True: 1.01M, False: 332k]
  ------------------
  393|  1.01M|                        stack.pop_back();
  394|   332k|                    calls--;
  395|   332k|                    return;
  396|  8.86M|                } break;
  397|       |
  398|   929k|                case FRAME_LOCAL: break;
  ------------------
  |  Branch (398:17): [True: 929k, False: 33.1M]
  ------------------
  399|       |
  400|  24.3M|                default: return;
  ------------------
  |  Branch (400:17): [True: 24.3M, False: 9.79M]
  ------------------
  401|  34.1M|            }
  402|  34.1M|        }
  403|  33.8M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15FrameC2ERKNS1_9FrameKindERKNS0_13LocationRangeE:
  208|  42.9M|    {
  209|  42.9M|        val.t = Value::NULL_TYPE;
  210|  42.9M|        val2.t = Value::NULL_TYPE;
  211|  42.9M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter22prepareSourceValThunksEv:
  864|  4.16k|    void prepareSourceValThunks() {
  865|   637k|        for (const auto &field : stdlibAST->fields) {
  ------------------
  |  Branch (865:32): [True: 637k, False: 4.16k]
  ------------------
  866|   637k|            AST *nameAST = field.name;
  867|   637k|            if (nameAST->type != AST_LITERAL_STRING) {
  ------------------
  |  Branch (867:17): [True: 0, False: 637k]
  ------------------
  868|       |                // Skip any fields without a known name.
  869|      0|                continue;
  870|      0|            }
  871|   637k|            UString name = dynamic_cast<LiteralString *>(nameAST)->value;
  872|       |
  873|   637k|            sourceFuncIds.emplace_back(new Identifier(name));
  874|   637k|            auto *th = makeHeap<HeapThunk>(sourceFuncIds.back().get(), stdObject, 0, field.body);
  875|   637k|            sourceVals[encode_utf8(name)] = th;
  876|   637k|        }
  877|  4.16k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJPNS0_10IdentifierERPNS1_10HeapObjectEiRKPNS0_3ASTEEEEPT_DpOT0_:
  567|   637k|    {
  568|   637k|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|   637k|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 0, False: 637k]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|      0|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|      0|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|      0|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|      0|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 0]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|      0|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 0, False: 0]
  ------------------
  587|      0|                heap.markFrom(sourceVal.second);
  588|      0|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|      0|            heap.sweep();
  592|      0|        }
  593|   637k|        return r;
  594|   637k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15StackD2Ev:
  250|  4.16k|    ~Stack(void) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8evaluateEPKNS0_3ASTEj:
 1989|  2.32M|    {
 1990|   102M|    recurse:
 1991|       |
 1992|   102M|        switch (ast_->type) {
 1993|  8.70M|            case AST_APPLY: {
  ------------------
  |  Branch (1993:13): [True: 8.70M, False: 93.8M]
  ------------------
 1994|  8.70M|                const auto &ast = *static_cast<const Apply *>(ast_);
 1995|  8.70M|                stack.newFrame(FRAME_APPLY_TARGET, ast_);
 1996|  8.70M|                ast_ = ast.target;
 1997|  8.70M|                goto recurse;
 1998|      0|            } break;
 1999|       |
 2000|   606k|            case AST_ARRAY: {
  ------------------
  |  Branch (2000:13): [True: 606k, False: 101M]
  ------------------
 2001|   606k|                const auto &ast = *static_cast<const Array *>(ast_);
 2002|   606k|                HeapObject *self;
 2003|   606k|                unsigned offset;
 2004|   606k|                stack.getSelfBinding(self, offset);
 2005|   606k|                scratch = makeArray({});
 2006|   606k|                auto &elements = static_cast<HeapArray *>(scratch.v.h)->elements;
 2007|  6.14M|                for (const auto &el : ast.elements) {
  ------------------
  |  Branch (2007:37): [True: 6.14M, False: 606k]
  ------------------
 2008|  6.14M|                    auto *el_th = makeHeap<HeapThunk>(idArrayElement, self, offset, el.expr);
 2009|  6.14M|                    el_th->upValues = capture(el.expr->freeVariables);
 2010|  6.14M|                    elements.push_back(el_th);
 2011|  6.14M|                }
 2012|   606k|            } break;
 2013|       |
 2014|  4.45M|            case AST_BINARY: {
  ------------------
  |  Branch (2014:13): [True: 4.45M, False: 98.1M]
  ------------------
 2015|  4.45M|                const auto &ast = *static_cast<const Binary *>(ast_);
 2016|  4.45M|                stack.newFrame(FRAME_BINARY_LEFT, ast_);
 2017|  4.45M|                ast_ = ast.left;
 2018|  4.45M|                goto recurse;
 2019|      0|            } break;
 2020|       |
 2021|  6.71M|            case AST_BUILTIN_FUNCTION: {
  ------------------
  |  Branch (2021:13): [True: 6.71M, False: 95.8M]
  ------------------
 2022|  6.71M|                const auto &ast = *static_cast<const BuiltinFunction *>(ast_);
 2023|  6.71M|                HeapClosure::Params params;
 2024|  6.71M|                params.reserve(ast.params.size());
 2025|  10.5M|                for (const auto &p : ast.params) {
  ------------------
  |  Branch (2025:36): [True: 10.5M, False: 6.71M]
  ------------------
 2026|       |                    // None of the builtins have default args.
 2027|  10.5M|                    params.emplace_back(p, nullptr);
 2028|  10.5M|                }
 2029|  6.71M|                scratch = makeBuiltin(ast.name, params);
 2030|  6.71M|            } break;
 2031|       |
 2032|  6.39M|            case AST_CONDITIONAL: {
  ------------------
  |  Branch (2032:13): [True: 6.39M, False: 96.1M]
  ------------------
 2033|  6.39M|                const auto &ast = *static_cast<const Conditional *>(ast_);
 2034|  6.39M|                stack.newFrame(FRAME_IF, ast_);
 2035|  6.39M|                ast_ = ast.cond;
 2036|  6.39M|                goto recurse;
 2037|      0|            } break;
 2038|       |
 2039|  4.35k|            case AST_ERROR: {
  ------------------
  |  Branch (2039:13): [True: 4.35k, False: 102M]
  ------------------
 2040|  4.35k|                const auto &ast = *static_cast<const Error *>(ast_);
 2041|  4.35k|                stack.newFrame(FRAME_ERROR, ast_);
 2042|  4.35k|                ast_ = ast.expr;
 2043|  4.35k|                goto recurse;
 2044|      0|            } break;
 2045|       |
 2046|  1.68M|            case AST_FUNCTION: {
  ------------------
  |  Branch (2046:13): [True: 1.68M, False: 100M]
  ------------------
 2047|  1.68M|                const auto &ast = *static_cast<const Function *>(ast_);
 2048|  1.68M|                auto env = capture(ast.freeVariables);
 2049|  1.68M|                HeapObject *self;
 2050|  1.68M|                unsigned offset;
 2051|  1.68M|                stack.getSelfBinding(self, offset);
 2052|  1.68M|                HeapClosure::Params params;
 2053|  1.68M|                params.reserve(ast.params.size());
 2054|  3.15M|                for (const auto &p : ast.params) {
  ------------------
  |  Branch (2054:36): [True: 3.15M, False: 1.68M]
  ------------------
 2055|  3.15M|                    params.emplace_back(p.id, p.expr);
 2056|  3.15M|                }
 2057|  1.68M|                scratch = makeClosure(env, self, offset, params, ast.body);
 2058|  1.68M|            } break;
 2059|       |
 2060|     89|            case AST_IMPORT: {
  ------------------
  |  Branch (2060:13): [True: 89, False: 102M]
  ------------------
 2061|     89|                const auto &ast = *static_cast<const Import *>(ast_);
 2062|     89|                HeapThunk *thunk = import(ast.location, ast.file);
 2063|     89|                if (thunk->filled) {
  ------------------
  |  Branch (2063:21): [True: 0, False: 89]
  ------------------
 2064|      0|                    scratch = thunk->content;
 2065|     89|                } else {
 2066|     89|                    stack.newCall(ast.location, thunk, thunk->self, thunk->offset, thunk->upValues);
 2067|     89|                    ast_ = thunk->body;
 2068|     89|                    goto recurse;
 2069|     89|                }
 2070|     89|            } break;
 2071|       |
 2072|      4|            case AST_IMPORTSTR: {
  ------------------
  |  Branch (2072:13): [True: 4, False: 102M]
  ------------------
 2073|      4|                const auto &ast = *static_cast<const Importstr *>(ast_);
 2074|      4|                const ImportCacheValue *value = importData(ast.location, ast.file);
 2075|      4|                scratch = makeString(decode_utf8(value->content));
 2076|      4|            } break;
 2077|       |
 2078|     12|            case AST_IMPORTBIN: {
  ------------------
  |  Branch (2078:13): [True: 12, False: 102M]
  ------------------
 2079|     12|                const auto &ast = *static_cast<const Importbin *>(ast_);
 2080|     12|                const ImportCacheValue *value = importData(ast.location, ast.file);
 2081|     12|                scratch = makeArray({});
 2082|     12|                auto &elements = static_cast<HeapArray *>(scratch.v.h)->elements;
 2083|     12|                elements.reserve(value->content.size());
 2084|     12|                for (const auto c : value->content) {
  ------------------
  |  Branch (2084:35): [True: 0, False: 12]
  ------------------
 2085|      0|                    auto *th = makeHeap<HeapThunk>(idArrayElement, nullptr, 0, nullptr);
 2086|      0|                    elements.push_back(th);
 2087|      0|                    th->fill(makeNumber(uint8_t(c)));
 2088|      0|                }
 2089|     12|            } break;
 2090|       |
 2091|  2.24M|            case AST_IN_SUPER: {
  ------------------
  |  Branch (2091:13): [True: 2.24M, False: 100M]
  ------------------
 2092|  2.24M|                const auto &ast = *static_cast<const InSuper *>(ast_);
 2093|  2.24M|                stack.newFrame(FRAME_IN_SUPER_ELEMENT, ast_);
 2094|  2.24M|                ast_ = ast.element;
 2095|  2.24M|                goto recurse;
 2096|     89|            } break;
 2097|       |
 2098|  8.83M|            case AST_INDEX: {
  ------------------
  |  Branch (2098:13): [True: 8.83M, False: 93.7M]
  ------------------
 2099|  8.83M|                const auto &ast = *static_cast<const Index *>(ast_);
 2100|  8.83M|                stack.newFrame(FRAME_INDEX_TARGET, ast_);
 2101|  8.83M|                ast_ = ast.target;
 2102|  8.83M|                goto recurse;
 2103|     89|            } break;
 2104|       |
 2105|  4.55M|            case AST_LOCAL: {
  ------------------
  |  Branch (2105:13): [True: 4.55M, False: 98.0M]
  ------------------
 2106|  4.55M|                const auto &ast = *static_cast<const Local *>(ast_);
 2107|  4.55M|                stack.newFrame(FRAME_LOCAL, ast_);
 2108|  4.55M|                Frame &f = stack.top();
 2109|       |                // First build all the thunks and bind them.
 2110|  4.55M|                HeapObject *self;
 2111|  4.55M|                unsigned offset;
 2112|  4.55M|                stack.getSelfBinding(self, offset);
 2113|  15.1M|                for (const auto &bind : ast.binds) {
  ------------------
  |  Branch (2113:39): [True: 15.1M, False: 4.55M]
  ------------------
 2114|       |                    // Note that these 2 lines must remain separate to avoid the GC running
 2115|       |                    // when bindings has a nullptr for key bind.first.
 2116|  15.1M|                    auto *th = makeHeap<HeapThunk>(bind.var, self, offset, bind.body);
 2117|  15.1M|                    f.bindings[bind.var] = th;
 2118|  15.1M|                }
 2119|       |                // Now capture the environment (including the new thunks, to make cycles).
 2120|  15.1M|                for (const auto &bind : ast.binds) {
  ------------------
  |  Branch (2120:39): [True: 15.1M, False: 4.55M]
  ------------------
 2121|  15.1M|                    auto *thunk = f.bindings[bind.var];
 2122|  15.1M|                    thunk->upValues = capture(bind.body->freeVariables);
 2123|  15.1M|                }
 2124|  4.55M|                ast_ = ast.body;
 2125|  4.55M|                goto recurse;
 2126|     89|            } break;
 2127|       |
 2128|   378k|            case AST_LITERAL_BOOLEAN: {
  ------------------
  |  Branch (2128:13): [True: 378k, False: 102M]
  ------------------
 2129|   378k|                const auto &ast = *static_cast<const LiteralBoolean *>(ast_);
 2130|   378k|                scratch = makeBoolean(ast.value);
 2131|   378k|            } break;
 2132|       |
 2133|  2.25M|            case AST_LITERAL_NUMBER: {
  ------------------
  |  Branch (2133:13): [True: 2.25M, False: 100M]
  ------------------
 2134|  2.25M|                const auto &ast = *static_cast<const LiteralNumber *>(ast_);
 2135|  2.25M|                scratch = makeNumberCheck(ast_->location, ast.value);
 2136|  2.25M|            } break;
 2137|       |
 2138|  27.1M|            case AST_LITERAL_STRING: {
  ------------------
  |  Branch (2138:13): [True: 27.1M, False: 75.3M]
  ------------------
 2139|  27.1M|                const auto &ast = *static_cast<const LiteralString *>(ast_);
 2140|  27.1M|                scratch = makeString(ast.value);
 2141|  27.1M|            } break;
 2142|       |
 2143|  88.2k|            case AST_LITERAL_NULL: {
  ------------------
  |  Branch (2143:13): [True: 88.2k, False: 102M]
  ------------------
 2144|  88.2k|                scratch = makeNull();
 2145|  88.2k|            } break;
 2146|       |
 2147|  1.58M|            case AST_DESUGARED_OBJECT: {
  ------------------
  |  Branch (2147:13): [True: 1.58M, False: 100M]
  ------------------
 2148|  1.58M|                const auto &ast = *static_cast<const DesugaredObject *>(ast_);
 2149|  1.58M|                if (ast.fields.empty()) {
  ------------------
  |  Branch (2149:21): [True: 1.16M, False: 416k]
  ------------------
 2150|  1.16M|                    auto env = capture(ast.freeVariables);
 2151|  1.16M|                    std::map<const Identifier *, HeapSimpleObject::Field> fields;
 2152|  1.16M|                    scratch = makeObject<HeapSimpleObject>(env, fields, ast.asserts);
 2153|  1.16M|                } else {
 2154|   416k|                    auto env = capture(ast.freeVariables);
 2155|   416k|                    stack.newFrame(FRAME_OBJECT, ast_);
 2156|   416k|                    auto fit = ast.fields.begin();
 2157|   416k|                    stack.top().fit = fit;
 2158|   416k|                    ast_ = fit->name;
 2159|   416k|                    goto recurse;
 2160|   416k|                }
 2161|  1.58M|            } break;
 2162|       |
 2163|  1.16M|            case AST_OBJECT_COMPREHENSION_SIMPLE: {
  ------------------
  |  Branch (2163:13): [True: 54, False: 102M]
  ------------------
 2164|     54|                const auto &ast = *static_cast<const ObjectComprehensionSimple *>(ast_);
 2165|     54|                stack.newFrame(FRAME_OBJECT_COMP_ARRAY, ast_);
 2166|     54|                ast_ = ast.array;
 2167|     54|                goto recurse;
 2168|  1.58M|            } break;
 2169|       |
 2170|  1.65M|            case AST_SELF: {
  ------------------
  |  Branch (2170:13): [True: 1.65M, False: 100M]
  ------------------
 2171|  1.65M|                scratch.t = Value::OBJECT;
 2172|  1.65M|                HeapObject *self;
 2173|  1.65M|                unsigned offset;
 2174|  1.65M|                stack.getSelfBinding(self, offset);
 2175|  1.65M|                scratch.v.h = self;
 2176|  1.65M|            } break;
 2177|       |
 2178|  2.05M|            case AST_SUPER_INDEX: {
  ------------------
  |  Branch (2178:13): [True: 2.05M, False: 100M]
  ------------------
 2179|  2.05M|                const auto &ast = *static_cast<const SuperIndex *>(ast_);
 2180|  2.05M|                stack.newFrame(FRAME_SUPER_INDEX, ast_);
 2181|  2.05M|                ast_ = ast.index;
 2182|  2.05M|                goto recurse;
 2183|  1.58M|            } break;
 2184|       |
 2185|  1.66M|            case AST_UNARY: {
  ------------------
  |  Branch (2185:13): [True: 1.66M, False: 100M]
  ------------------
 2186|  1.66M|                const auto &ast = *static_cast<const Unary *>(ast_);
 2187|  1.66M|                stack.newFrame(FRAME_UNARY, ast_);
 2188|  1.66M|                ast_ = ast.expr;
 2189|  1.66M|                goto recurse;
 2190|  1.58M|            } break;
 2191|       |
 2192|  21.5M|            case AST_VAR: {
  ------------------
  |  Branch (2192:13): [True: 21.5M, False: 81.0M]
  ------------------
 2193|  21.5M|                const auto &ast = *static_cast<const Var *>(ast_);
 2194|  21.5M|                auto *thunk = stack.lookUpVar(ast.id);
 2195|  21.5M|                if (thunk == nullptr) {
  ------------------
  |  Branch (2195:21): [True: 0, False: 21.5M]
  ------------------
 2196|      0|                    std::cerr << "INTERNAL ERROR: Could not bind variable: "
 2197|      0|                              << encode_utf8(ast.id->name) << " at "
 2198|      0|                              << ast.location << std::endl;
 2199|      0|                    std::abort();
 2200|      0|                }
 2201|  21.5M|                if (thunk->filled) {
  ------------------
  |  Branch (2201:21): [True: 16.0M, False: 5.41M]
  ------------------
 2202|  16.0M|                    scratch = thunk->content;
 2203|  16.0M|                } else {
 2204|  5.41M|                    stack.newCall(ast.location, thunk, thunk->self, thunk->offset, thunk->upValues);
 2205|  5.41M|                    ast_ = thunk->body;
 2206|  5.41M|                    goto recurse;
 2207|  5.41M|                }
 2208|  21.5M|            } break;
 2209|       |
 2210|  16.0M|            default:
  ------------------
  |  Branch (2210:13): [True: 0, False: 102M]
  ------------------
 2211|      0|                std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_->type << std::endl;
 2212|      0|                std::abort();
 2213|   102M|        }
 2214|       |
 2215|       |        // To evaluate another AST, set ast to it, then goto recurse.
 2216|       |        // To pop, exit the switch or goto popframe
 2217|       |        // To change the frame and re-enter the switch, goto replaceframe
 2218|   117M|        while (stack.size() > initial_stack_size) {
  ------------------
  |  Branch (2218:16): [True: 115M, False: 2.31M]
  ------------------
 2219|   115M|            Frame &f = stack.top();
 2220|   115M|            switch (f.kind) {
 2221|  8.70M|                case FRAME_APPLY_TARGET: {
  ------------------
  |  Branch (2221:17): [True: 8.70M, False: 106M]
  ------------------
 2222|  8.70M|                    const auto &ast = *static_cast<const Apply *>(f.ast);
 2223|  8.70M|                    if (scratch.t != Value::FUNCTION) {
  ------------------
  |  Branch (2223:25): [True: 18, False: 8.70M]
  ------------------
 2224|     18|                        throw makeError(ast.location,
 2225|     18|                                        "only functions can be called, got " + type_str(scratch));
 2226|     18|                    }
 2227|  8.70M|                    auto *func = static_cast<HeapClosure *>(scratch.v.h);
 2228|       |
 2229|  8.70M|                    std::set<const Identifier *> params_needed;
 2230|  14.7M|                    for (const auto &param : func->params) {
  ------------------
  |  Branch (2230:44): [True: 14.7M, False: 8.70M]
  ------------------
 2231|  14.7M|                        params_needed.insert(param.id);
 2232|  14.7M|                    }
 2233|       |
 2234|       |                    // Create thunks for arguments.
 2235|  8.70M|                    std::vector<HeapThunk *> positional_args;
 2236|  8.70M|                    BindingFrame args;
 2237|  8.70M|                    bool got_named = false;
 2238|  23.4M|                    for (std::size_t i = 0; i < ast.args.size(); ++i) {
  ------------------
  |  Branch (2238:45): [True: 14.7M, False: 8.70M]
  ------------------
 2239|  14.7M|                        const auto &arg = ast.args[i];
 2240|       |
 2241|  14.7M|                        const Identifier *name;
 2242|  14.7M|                        if (arg.id != nullptr) {
  ------------------
  |  Branch (2242:29): [True: 0, False: 14.7M]
  ------------------
 2243|      0|                            got_named = true;
 2244|      0|                            name = arg.id;
 2245|  14.7M|                        } else {
 2246|  14.7M|                            if (got_named) {
  ------------------
  |  Branch (2246:33): [True: 0, False: 14.7M]
  ------------------
 2247|      0|                                std::stringstream ss;
 2248|      0|                                ss << "internal error: got positional param after named at index "
 2249|      0|                                   << i;
 2250|      0|                                throw makeError(ast.location, ss.str());
 2251|      0|                            }
 2252|  14.7M|                            if (i >= func->params.size()) {
  ------------------
  |  Branch (2252:33): [True: 0, False: 14.7M]
  ------------------
 2253|      0|                                std::stringstream ss;
 2254|      0|                                ss << "too many args, function has " << func->params.size()
 2255|      0|                                   << " parameter(s)";
 2256|      0|                                throw makeError(ast.location, ss.str());
 2257|      0|                            }
 2258|  14.7M|                            name = func->params[i].id;
 2259|  14.7M|                        }
 2260|       |                        // Special case for builtin functions -- leave identifier blank for
 2261|       |                        // them in the thunk.  This removes the thunk frame from the stacktrace.
 2262|  14.7M|                        const Identifier *name_ = func->body == nullptr ? nullptr : name;
  ------------------
  |  Branch (2262:51): [True: 10.5M, False: 4.14M]
  ------------------
 2263|  14.7M|                        HeapObject *self;
 2264|  14.7M|                        unsigned offset;
 2265|  14.7M|                        stack.getSelfBinding(self, offset);
 2266|  14.7M|                        auto *thunk = makeHeap<HeapThunk>(name_, self, offset, arg.expr);
 2267|  14.7M|                        thunk->upValues = capture(arg.expr->freeVariables);
 2268|       |                        // While making the thunks, keep them in a frame to avoid premature garbage
 2269|       |                        // collection.
 2270|  14.7M|                        f.thunks.push_back(thunk);
 2271|  14.7M|                        if (args.find(name) != args.end()) {
  ------------------
  |  Branch (2271:29): [True: 0, False: 14.7M]
  ------------------
 2272|      0|                            std::stringstream ss;
 2273|      0|                            ss << "binding parameter a second time: " << encode_utf8(name->name);
 2274|      0|                            throw makeError(ast.location, ss.str());
 2275|      0|                        }
 2276|  14.7M|                        args[name] = thunk;
 2277|  14.7M|                        if (params_needed.find(name) == params_needed.end()) {
  ------------------
  |  Branch (2277:29): [True: 0, False: 14.7M]
  ------------------
 2278|      0|                            std::stringstream ss;
 2279|      0|                            ss << "function has no parameter " << encode_utf8(name->name);
 2280|      0|                            throw makeError(ast.location, ss.str());
 2281|      0|                        }
 2282|  14.7M|                    }
 2283|       |
 2284|       |                    // For any func params for which there was no arg, create a thunk for those and
 2285|       |                    // bind the default argument.  Allow default thunks to see other params.  If no
 2286|       |                    // default argument than raise an error.
 2287|       |
 2288|       |                    // Raise errors for unbound params, create thunks (but don't fill in upvalues).
 2289|       |                    // This is a subset of f.thunks, so will not get garbage collected.
 2290|  8.70M|                    std::vector<HeapThunk *> def_arg_thunks;
 2291|  14.7M|                    for (const auto &param : func->params) {
  ------------------
  |  Branch (2291:44): [True: 14.7M, False: 8.70M]
  ------------------
 2292|  14.7M|                        if (args.find(param.id) != args.end())
  ------------------
  |  Branch (2292:29): [True: 14.7M, False: 40]
  ------------------
 2293|  14.7M|                            continue;
 2294|     40|                        if (param.def == nullptr) {
  ------------------
  |  Branch (2294:29): [True: 3, False: 37]
  ------------------
 2295|      3|                            std::stringstream ss;
 2296|      3|                            ss << "function parameter " << encode_utf8(param.id->name)
 2297|      3|                               << " not bound in call.";
 2298|      3|                            throw makeError(ast.location, ss.str());
 2299|      3|                        }
 2300|       |
 2301|       |                        // Special case for builtin functions -- leave identifier blank for
 2302|       |                        // them in the thunk.  This removes the thunk frame from the stacktrace.
 2303|     37|                        const Identifier *name_ = func->body == nullptr ? nullptr : param.id;
  ------------------
  |  Branch (2303:51): [True: 0, False: 37]
  ------------------
 2304|     37|                        auto *thunk =
 2305|     37|                            makeHeap<HeapThunk>(name_, func->self, func->offset, param.def);
 2306|     37|                        f.thunks.push_back(thunk);
 2307|     37|                        def_arg_thunks.push_back(thunk);
 2308|     37|                        args[param.id] = thunk;
 2309|     37|                    }
 2310|       |
 2311|  8.70M|                    BindingFrame up_values = func->upValues;
 2312|  8.70M|                    up_values.insert(args.begin(), args.end());
 2313|       |
 2314|       |                    // Fill in upvalues
 2315|  8.70M|                    for (HeapThunk *thunk : def_arg_thunks) {
  ------------------
  |  Branch (2315:43): [True: 36, False: 8.70M]
  ------------------
 2316|     36|                        thunk->upValues = up_values;
 2317|     36|                    }
 2318|       |
 2319|       |                    // Cache these, because pop will invalidate them.
 2320|  8.70M|                    std::vector<HeapThunk *> thunks_copy = f.thunks;
 2321|       |
 2322|  8.70M|                    const AST *f_ast = f.ast;
 2323|  8.70M|                    stack.pop();
 2324|       |
 2325|  8.70M|                    if (func->body == nullptr) {
  ------------------
  |  Branch (2325:25): [True: 6.71M, False: 1.99M]
  ------------------
 2326|       |                        // Built-in function.
 2327|       |                        // Give nullptr for self because no one looking at this frame will
 2328|       |                        // attempt to bind to self (it's native code).
 2329|  6.71M|                        stack.newFrame(FRAME_BUILTIN_FORCE_THUNKS, f_ast);
 2330|  6.71M|                        stack.top().thunks = thunks_copy;
 2331|  6.71M|                        stack.top().val = scratch;
 2332|  6.71M|                        goto replaceframe;
 2333|  6.71M|                    } else {
 2334|       |                        // User defined function.
 2335|  1.99M|                        stack.newCall(ast.location, func, func->self, func->offset, up_values);
 2336|  1.99M|                        if (ast.tailstrict) {
  ------------------
  |  Branch (2336:29): [True: 1.25M, False: 732k]
  ------------------
 2337|  1.25M|                            stack.top().tailCall = true;
 2338|  1.25M|                            if (thunks_copy.size() == 0) {
  ------------------
  |  Branch (2338:33): [True: 0, False: 1.25M]
  ------------------
 2339|       |                                // No need to force thunks, proceed straight to body.
 2340|      0|                                ast_ = func->body;
 2341|      0|                                goto recurse;
 2342|  1.25M|                            } else {
 2343|       |                                // The check for args.size() > 0
 2344|  1.25M|                                stack.top().thunks = thunks_copy;
 2345|  1.25M|                                stack.top().val = scratch;
 2346|  1.25M|                                goto replaceframe;
 2347|  1.25M|                            }
 2348|  1.25M|                        } else {
 2349|   732k|                            ast_ = func->body;
 2350|   732k|                            goto recurse;
 2351|   732k|                        }
 2352|  1.99M|                    }
 2353|  8.70M|                } break;
 2354|       |
 2355|  4.28M|                case FRAME_BINARY_LEFT: {
  ------------------
  |  Branch (2355:17): [True: 4.28M, False: 111M]
  ------------------
 2356|  4.28M|                    const auto &ast = *static_cast<const Binary *>(f.ast);
 2357|  4.28M|                    const Value &lhs = scratch;
 2358|  4.28M|                    if (lhs.t == Value::BOOLEAN) {
  ------------------
  |  Branch (2358:25): [True: 184k, False: 4.10M]
  ------------------
 2359|       |                        // Handle short-cut semantics
 2360|   184k|                        switch (ast.op) {
 2361|   105k|                            case BOP_AND: {
  ------------------
  |  Branch (2361:29): [True: 105k, False: 79.8k]
  ------------------
 2362|   105k|                                if (!lhs.v.b) {
  ------------------
  |  Branch (2362:37): [True: 6.47k, False: 98.5k]
  ------------------
 2363|  6.47k|                                    scratch = makeBoolean(false);
 2364|  6.47k|                                    goto popframe;
 2365|  6.47k|                                }
 2366|   105k|                            } break;
 2367|       |
 2368|  98.5k|                            case BOP_OR: {
  ------------------
  |  Branch (2368:29): [True: 77.4k, False: 107k]
  ------------------
 2369|  77.4k|                                if (lhs.v.b) {
  ------------------
  |  Branch (2369:37): [True: 2.18k, False: 75.2k]
  ------------------
 2370|  2.18k|                                    scratch = makeBoolean(true);
 2371|  2.18k|                                    goto popframe;
 2372|  2.18k|                                }
 2373|  77.4k|                            } break;
 2374|       |
 2375|  75.2k|                            default:;
  ------------------
  |  Branch (2375:29): [True: 2.36k, False: 182k]
  ------------------
 2376|   184k|                        }
 2377|   184k|                    }
 2378|  4.27M|                    stack.top().kind = FRAME_BINARY_RIGHT;
 2379|  4.27M|                    stack.top().val = lhs;
 2380|  4.27M|                    ast_ = ast.right;
 2381|  4.27M|                    goto recurse;
 2382|  4.28M|                } break;
 2383|       |
 2384|  4.27M|                case FRAME_BINARY_RIGHT: {
  ------------------
  |  Branch (2384:17): [True: 4.27M, False: 111M]
  ------------------
 2385|  4.27M|                    stack.top().val2 = scratch;
 2386|  4.27M|                    stack.top().kind = FRAME_BINARY_OP;
 2387|  4.27M|                }
 2388|       |                // Falls through.
 2389|  4.27M|                case FRAME_BINARY_OP: {
  ------------------
  |  Branch (2389:17): [True: 102, False: 115M]
  ------------------
 2390|  4.27M|                    const auto &ast = *static_cast<const Binary *>(f.ast);
 2391|  4.27M|                    const Value &lhs = stack.top().val;
 2392|  4.27M|                    const Value &rhs = stack.top().val2;
 2393|       |
 2394|       |                    // Handle cases where the LHS and RHS are not the same type.
 2395|  4.27M|                    if (lhs.t == Value::STRING || rhs.t == Value::STRING) {
  ------------------
  |  Branch (2395:25): [True: 1.72M, False: 2.54M]
  |  Branch (2395:51): [True: 141k, False: 2.40M]
  ------------------
 2396|  1.86M|                        if (ast.op == BOP_PLUS) {
  ------------------
  |  Branch (2396:29): [True: 1.79M, False: 71.0k]
  ------------------
 2397|       |                            // Handle co-ercions for string processing.
 2398|  1.79M|                            stack.top().kind = FRAME_STRING_CONCAT;
 2399|  1.79M|                            stack.top().val2 = rhs;
 2400|  1.79M|                            goto replaceframe;
 2401|  1.79M|                        }
 2402|  1.86M|                    }
 2403|  2.47M|                    switch (ast.op) {
 2404|       |                        // Equality can be used when the types don't match.
 2405|      0|                        case BOP_MANIFEST_EQUAL:
  ------------------
  |  Branch (2405:25): [True: 0, False: 2.47M]
  ------------------
 2406|      0|                            std::cerr << "INTERNAL ERROR: Equals not desugared" << std::endl;
 2407|      0|                            abort();
 2408|       |
 2409|       |                        // Equality can be used when the types don't match.
 2410|      0|                        case BOP_MANIFEST_UNEQUAL:
  ------------------
  |  Branch (2410:25): [True: 0, False: 2.47M]
  ------------------
 2411|      0|                            std::cerr << "INTERNAL ERROR: Notequals not desugared" << std::endl;
 2412|      0|                            abort();
 2413|       |
 2414|       |                        // e in e
 2415|     11|                        case BOP_IN: {
  ------------------
  |  Branch (2415:25): [True: 11, False: 2.47M]
  ------------------
 2416|     11|                            if (lhs.t != Value::STRING) {
  ------------------
  |  Branch (2416:33): [True: 2, False: 9]
  ------------------
 2417|      2|                                throw makeError(ast.location,
 2418|      2|                                                "the left hand side of the 'in' operator should be "
 2419|      2|                                                "a string,  got " +
 2420|      2|                                                    type_str(lhs));
 2421|      2|                            }
 2422|      9|                            auto *field = static_cast<HeapString *>(lhs.v.h);
 2423|      9|                            switch (rhs.t) {
 2424|      8|                                case Value::OBJECT: {
  ------------------
  |  Branch (2424:33): [True: 8, False: 1]
  ------------------
 2425|      8|                                    auto *obj = static_cast<HeapObject *>(rhs.v.h);
 2426|      8|                                    auto *fid = alloc->makeIdentifier(field->value);
 2427|      8|                                    unsigned unused_found_at = 0;
 2428|      8|                                    bool in = findObject(fid, obj, 0, unused_found_at);
 2429|      8|                                    scratch = makeBoolean(in);
 2430|      8|                                } break;
 2431|       |
 2432|      1|                                default:
  ------------------
  |  Branch (2432:33): [True: 1, False: 8]
  ------------------
 2433|      1|                                    throw makeError(
 2434|      1|                                        ast.location,
 2435|      1|                                        "the right hand side of the 'in' operator should be"
 2436|      1|                                        " an object, got " +
 2437|      1|                                            type_str(rhs));
 2438|      9|                            }
 2439|      8|                            goto popframe;
 2440|      9|                        }
 2441|       |
 2442|  2.47M|                        default:;
  ------------------
  |  Branch (2442:25): [True: 2.47M, False: 11]
  ------------------
 2443|  2.47M|                    }
 2444|       |                    // Everything else requires matching types.
 2445|  2.47M|                    if (lhs.t != rhs.t) {
  ------------------
  |  Branch (2445:25): [True: 111, False: 2.47M]
  ------------------
 2446|    111|                        throw makeError(ast.location,
 2447|    111|                                        "binary operator " + bop_string(ast.op) +
 2448|    111|                                            " requires "
 2449|    111|                                            "matching types, got " +
 2450|    111|                                            type_str(lhs) + " and " + type_str(rhs) + ".");
 2451|    111|                    }
 2452|  2.47M|                    switch (lhs.t) {
  ------------------
  |  Branch (2452:29): [True: 0, False: 2.47M]
  ------------------
 2453|   404k|                        case Value::ARRAY:
  ------------------
  |  Branch (2453:25): [True: 404k, False: 2.07M]
  ------------------
 2454|   404k|                            if (ast.op == BOP_PLUS) {
  ------------------
  |  Branch (2454:33): [True: 394k, False: 9.86k]
  ------------------
 2455|   394k|                                auto *arr_l = static_cast<HeapArray *>(lhs.v.h);
 2456|   394k|                                auto *arr_r = static_cast<HeapArray *>(rhs.v.h);
 2457|   394k|                                std::vector<HeapThunk *> elements;
 2458|   394k|                                for (auto *el : arr_l->elements)
  ------------------
  |  Branch (2458:47): [True: 20.0M, False: 394k]
  ------------------
 2459|  20.0M|                                    elements.push_back(el);
 2460|   394k|                                for (auto *el : arr_r->elements)
  ------------------
  |  Branch (2460:47): [True: 212k, False: 394k]
  ------------------
 2461|   212k|                                    elements.push_back(el);
 2462|   394k|                                scratch = makeArray(elements);
 2463|   394k|                            } else if (ast.op == BOP_LESS || ast.op == BOP_LESS_EQ || ast.op == BOP_GREATER || ast.op == BOP_GREATER_EQ) {
  ------------------
  |  Branch (2463:40): [True: 6.86k, False: 2.99k]
  |  Branch (2463:62): [True: 278, False: 2.71k]
  |  Branch (2463:87): [True: 819, False: 1.89k]
  |  Branch (2463:112): [True: 1.89k, False: 5]
  ------------------
 2464|  9.85k|                                HeapThunk *func;
 2465|  9.85k|                                switch(ast.op) {
 2466|  6.86k|                                case BOP_LESS:
  ------------------
  |  Branch (2466:33): [True: 6.86k, False: 2.99k]
  ------------------
 2467|  6.86k|                                    func = sourceVals["__array_less"];
 2468|  6.86k|                                    break;
 2469|    278|                                case BOP_LESS_EQ:
  ------------------
  |  Branch (2469:33): [True: 278, False: 9.58k]
  ------------------
 2470|    278|                                    func = sourceVals["__array_less_or_equal"];
 2471|    278|                                    break;
 2472|    819|                                case BOP_GREATER:
  ------------------
  |  Branch (2472:33): [True: 819, False: 9.04k]
  ------------------
 2473|    819|                                    func = sourceVals["__array_greater"];
 2474|    819|                                    break;
 2475|  1.89k|                                case BOP_GREATER_EQ:
  ------------------
  |  Branch (2475:33): [True: 1.89k, False: 7.96k]
  ------------------
 2476|  1.89k|                                    func = sourceVals["__array_greater_or_equal"];
 2477|  1.89k|                                    break;
 2478|      0|                                default:
  ------------------
  |  Branch (2478:33): [True: 0, False: 9.85k]
  ------------------
 2479|      0|                                    JSONNET_UNREACHABLE();
  ------------------
  |  |   43|      0|  do {                                                             \
  |  |   44|      0|    std::cerr << __FILE__ << ":" << __LINE__                       \
  |  |   45|      0|              << ": INTERNAL ERROR: reached unreachable code path" \
  |  |   46|      0|              << std::endl;                                        \
  |  |   47|      0|    abort();                                                       \
  |  |   48|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (48:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 2480|  9.85k|                                }
 2481|  9.85k|                                if (!func->filled) {
  ------------------
  |  Branch (2481:37): [True: 102, False: 9.75k]
  ------------------
 2482|    102|                                    stack.newCall(ast.location, func, func->self, func->offset, func->upValues);
 2483|    102|                                    ast_ = func->body;
 2484|    102|                                    goto recurse;
 2485|    102|                                }
 2486|  9.75k|                                auto *lhs_th = makeHeap<HeapThunk>(idInternal, f.self, f.offset, ast.left);
 2487|  9.75k|                                lhs_th->fill(lhs);
 2488|  9.75k|                                f.thunks.push_back(lhs_th);
 2489|  9.75k|                                auto *rhs_th = makeHeap<HeapThunk>(idInternal, f.self, f.offset, ast.right);
 2490|  9.75k|                                rhs_th->fill(rhs);
 2491|  9.75k|                                f.thunks.push_back(rhs_th);
 2492|  9.75k|                                const AST *orig_ast = ast_;
 2493|  9.75k|                                stack.pop();
 2494|  9.75k|                                ast_ = callSourceVal(orig_ast, func, {lhs_th, rhs_th});
 2495|  9.75k|                                goto recurse;
 2496|  9.85k|                            } else {
 2497|      5|                                throw makeError(ast.location,
 2498|      5|                                                "binary operator " + bop_string(ast.op) +
 2499|      5|                                                    " does not operate on arrays.");
 2500|      5|                            }
 2501|   394k|                            break;
 2502|       |
 2503|   394k|                        case Value::BOOLEAN:
  ------------------
  |  Branch (2503:25): [True: 172k, False: 2.30M]
  ------------------
 2504|   172k|                            switch (ast.op) {
 2505|  97.5k|                                case BOP_AND: scratch = makeBoolean(lhs.v.b && rhs.v.b); break;
  ------------------
  |  Branch (2505:33): [True: 97.5k, False: 75.2k]
  |  Branch (2505:69): [True: 97.5k, False: 0]
  |  Branch (2505:80): [True: 93.8k, False: 3.69k]
  ------------------
 2506|       |
 2507|  75.2k|                                case BOP_OR: scratch = makeBoolean(lhs.v.b || rhs.v.b); break;
  ------------------
  |  Branch (2507:33): [True: 75.2k, False: 97.5k]
  |  Branch (2507:68): [True: 0, False: 75.2k]
  |  Branch (2507:79): [True: 3.05k, False: 72.2k]
  ------------------
 2508|       |
 2509|     11|                                default:
  ------------------
  |  Branch (2509:33): [True: 11, False: 172k]
  ------------------
 2510|     11|                                    throw makeError(ast.location,
 2511|     11|                                                    "binary operator " + bop_string(ast.op) +
 2512|     11|                                                        " does not operate on booleans.");
 2513|   172k|                            }
 2514|   172k|                            break;
 2515|       |
 2516|   873k|                        case Value::NUMBER:
  ------------------
  |  Branch (2516:25): [True: 873k, False: 1.60M]
  ------------------
 2517|   873k|                            switch (ast.op) {
 2518|   263k|                                case BOP_PLUS:
  ------------------
  |  Branch (2518:33): [True: 263k, False: 610k]
  ------------------
 2519|   263k|                                    scratch = makeNumberCheck(ast.location, lhs.v.d + rhs.v.d);
 2520|   263k|                                    break;
 2521|       |
 2522|  55.4k|                                case BOP_MINUS:
  ------------------
  |  Branch (2522:33): [True: 55.4k, False: 818k]
  ------------------
 2523|  55.4k|                                    scratch = makeNumberCheck(ast.location, lhs.v.d - rhs.v.d);
 2524|  55.4k|                                    break;
 2525|       |
 2526|  3.95k|                                case BOP_MULT:
  ------------------
  |  Branch (2526:33): [True: 3.95k, False: 869k]
  ------------------
 2527|  3.95k|                                    scratch = makeNumberCheck(ast.location, lhs.v.d * rhs.v.d);
 2528|  3.95k|                                    break;
 2529|       |
 2530|  15.1k|                                case BOP_DIV:
  ------------------
  |  Branch (2530:33): [True: 15.1k, False: 858k]
  ------------------
 2531|  15.1k|                                    if (rhs.v.d == 0)
  ------------------
  |  Branch (2531:41): [True: 3, False: 15.1k]
  ------------------
 2532|      3|                                        throw makeError(ast.location, "division by zero.");
 2533|  15.1k|                                    scratch = makeNumberCheck(ast.location, lhs.v.d / rhs.v.d);
 2534|  15.1k|                                    break;
 2535|       |
 2536|       |                                    // No need to check doubles made from longs
 2537|       |
 2538|     68|                                case BOP_SHIFT_L: {
  ------------------
  |  Branch (2538:33): [True: 68, False: 873k]
  ------------------
 2539|     68|                                    if (rhs.v.d < 0)
  ------------------
  |  Branch (2539:41): [True: 1, False: 67]
  ------------------
 2540|      1|                                        throw makeError(ast.location, "shift by negative exponent.");
 2541|     67|                                    int64_t long_l = lhs.v.d;
 2542|     67|                                    int64_t long_r = rhs.v.d;
 2543|     67|                                    long_r = long_r % 64;
 2544|     67|                                    scratch = makeNumber(long_l << long_r);
 2545|     67|                                } break;
 2546|       |
 2547|  1.33k|                                case BOP_SHIFT_R: {
  ------------------
  |  Branch (2547:33): [True: 1.33k, False: 872k]
  ------------------
 2548|  1.33k|                                    if (rhs.v.d < 0)
  ------------------
  |  Branch (2548:41): [True: 2, False: 1.33k]
  ------------------
 2549|      2|                                        throw makeError(ast.location, "shift by negative exponent.");
 2550|  1.33k|                                    int64_t long_l = lhs.v.d;
 2551|  1.33k|                                    int64_t long_r = rhs.v.d;
 2552|  1.33k|                                    long_r = long_r % 64;
 2553|  1.33k|                                    scratch = makeNumber(long_l >> long_r);
 2554|  1.33k|                                } break;
 2555|       |
 2556|  1.81k|                                case BOP_BITWISE_AND: {
  ------------------
  |  Branch (2556:33): [True: 1.81k, False: 871k]
  ------------------
 2557|  1.81k|                                    int64_t long_l = lhs.v.d;
 2558|  1.81k|                                    int64_t long_r = rhs.v.d;
 2559|  1.81k|                                    scratch = makeNumber(long_l & long_r);
 2560|  1.81k|                                } break;
 2561|       |
 2562|    377|                                case BOP_BITWISE_XOR: {
  ------------------
  |  Branch (2562:33): [True: 377, False: 873k]
  ------------------
 2563|    377|                                    int64_t long_l = lhs.v.d;
 2564|    377|                                    int64_t long_r = rhs.v.d;
 2565|    377|                                    scratch = makeNumber(long_l ^ long_r);
 2566|    377|                                } break;
 2567|       |
 2568|    828|                                case BOP_BITWISE_OR: {
  ------------------
  |  Branch (2568:33): [True: 828, False: 872k]
  ------------------
 2569|    828|                                    int64_t long_l = lhs.v.d;
 2570|    828|                                    int64_t long_r = rhs.v.d;
 2571|    828|                                    scratch = makeNumber(long_l | long_r);
 2572|    828|                                } break;
 2573|       |
 2574|  35.6k|                                case BOP_LESS_EQ: scratch = makeBoolean(lhs.v.d <= rhs.v.d); break;
  ------------------
  |  Branch (2574:33): [True: 35.6k, False: 838k]
  ------------------
 2575|       |
 2576|   406k|                                case BOP_GREATER_EQ:
  ------------------
  |  Branch (2576:33): [True: 406k, False: 467k]
  ------------------
 2577|   406k|                                    scratch = makeBoolean(lhs.v.d >= rhs.v.d);
 2578|   406k|                                    break;
 2579|       |
 2580|  70.4k|                                case BOP_LESS: scratch = makeBoolean(lhs.v.d < rhs.v.d); break;
  ------------------
  |  Branch (2580:33): [True: 70.4k, False: 803k]
  ------------------
 2581|       |
 2582|  18.8k|                                case BOP_GREATER: scratch = makeBoolean(lhs.v.d > rhs.v.d); break;
  ------------------
  |  Branch (2582:33): [True: 18.8k, False: 854k]
  ------------------
 2583|       |
 2584|      8|                                default:
  ------------------
  |  Branch (2584:33): [True: 8, False: 873k]
  ------------------
 2585|      8|                                    throw makeError(ast.location,
 2586|      8|                                                    "binary operator " + bop_string(ast.op) +
 2587|      8|                                                        " does not operate on numbers.");
 2588|   873k|                            }
 2589|   873k|                            break;
 2590|       |
 2591|   873k|                        case Value::FUNCTION:
  ------------------
  |  Branch (2591:25): [True: 0, False: 2.47M]
  ------------------
 2592|      0|                            throw makeError(ast.location,
 2593|      0|                                            "binary operator " + bop_string(ast.op) +
 2594|      0|                                                " does not operate on functions.");
 2595|       |
 2596|      1|                        case Value::NULL_TYPE:
  ------------------
  |  Branch (2596:25): [True: 1, False: 2.47M]
  ------------------
 2597|      1|                            throw makeError(ast.location,
 2598|      1|                                            "binary operator " + bop_string(ast.op) +
 2599|      1|                                                " does not operate on null.");
 2600|       |
 2601|   954k|                        case Value::OBJECT: {
  ------------------
  |  Branch (2601:25): [True: 954k, False: 1.52M]
  ------------------
 2602|   954k|                            if (ast.op != BOP_PLUS) {
  ------------------
  |  Branch (2602:33): [True: 13, False: 954k]
  ------------------
 2603|     13|                                throw makeError(ast.location,
 2604|     13|                                                "binary operator " + bop_string(ast.op) +
 2605|     13|                                                    " does not operate on objects.");
 2606|     13|                            }
 2607|   954k|                            auto *lhs_obj = static_cast<HeapObject *>(lhs.v.h);
 2608|   954k|                            auto *rhs_obj = static_cast<HeapObject *>(rhs.v.h);
 2609|   954k|                            scratch = makeObject<HeapExtendedObject>(lhs_obj, rhs_obj);
 2610|   954k|                        } break;
 2611|       |
 2612|  70.9k|                        case Value::STRING: {
  ------------------
  |  Branch (2612:25): [True: 70.9k, False: 2.40M]
  ------------------
 2613|  70.9k|                            const UString &lhs_str = static_cast<HeapString *>(lhs.v.h)->value;
 2614|  70.9k|                            const UString &rhs_str = static_cast<HeapString *>(rhs.v.h)->value;
 2615|  70.9k|                            switch (ast.op) {
 2616|      0|                                case BOP_PLUS: scratch = makeString(lhs_str + rhs_str); break;
  ------------------
  |  Branch (2616:33): [True: 0, False: 70.9k]
  ------------------
 2617|       |
 2618|  5.62k|                                case BOP_LESS_EQ: scratch = makeBoolean(lhs_str <= rhs_str); break;
  ------------------
  |  Branch (2618:33): [True: 5.62k, False: 65.3k]
  ------------------
 2619|       |
 2620|  30.5k|                                case BOP_GREATER_EQ:
  ------------------
  |  Branch (2620:33): [True: 30.5k, False: 40.4k]
  ------------------
 2621|  30.5k|                                    scratch = makeBoolean(lhs_str >= rhs_str);
 2622|  30.5k|                                    break;
 2623|       |
 2624|  6.09k|                                case BOP_LESS: scratch = makeBoolean(lhs_str < rhs_str); break;
  ------------------
  |  Branch (2624:33): [True: 6.09k, False: 64.8k]
  ------------------
 2625|       |
 2626|  28.7k|                                case BOP_GREATER: scratch = makeBoolean(lhs_str > rhs_str); break;
  ------------------
  |  Branch (2626:33): [True: 28.7k, False: 42.2k]
  ------------------
 2627|       |
 2628|     14|                                default:
  ------------------
  |  Branch (2628:33): [True: 14, False: 70.9k]
  ------------------
 2629|     14|                                    throw makeError(ast.location,
 2630|     14|                                                    "binary operator " + bop_string(ast.op) +
 2631|     14|                                                        " does not operate on strings.");
 2632|  70.9k|                            }
 2633|  70.9k|                        } break;
 2634|  2.47M|                    }
 2635|  2.47M|                } break;
 2636|       |
 2637|  2.46M|                case FRAME_BUILTIN_FILTER: {
  ------------------
  |  Branch (2637:17): [True: 0, False: 115M]
  ------------------
 2638|      0|                    const auto &ast = *static_cast<const Apply *>(f.ast);
 2639|      0|                    auto *func = static_cast<HeapClosure *>(f.val.v.h);
 2640|      0|                    auto *arr = static_cast<HeapArray *>(f.val2.v.h);
 2641|      0|                    if (scratch.t != Value::BOOLEAN) {
  ------------------
  |  Branch (2641:25): [True: 0, False: 0]
  ------------------
 2642|      0|                        throw makeError(
 2643|      0|                            ast.location,
 2644|      0|                            "filter function must return boolean, got: " + type_str(scratch));
 2645|      0|                    }
 2646|      0|                    if (scratch.v.b)
  ------------------
  |  Branch (2646:25): [True: 0, False: 0]
  ------------------
 2647|      0|                        f.thunks.push_back(arr->elements[f.elementId]);
 2648|      0|                    f.elementId++;
 2649|       |                    // Iterate through arr, calling the function on each.
 2650|      0|                    if (f.elementId == arr->elements.size()) {
  ------------------
  |  Branch (2650:25): [True: 0, False: 0]
  ------------------
 2651|      0|                        scratch = makeArray(f.thunks);
 2652|      0|                    } else {
 2653|      0|                        auto *thunk = arr->elements[f.elementId];
 2654|      0|                        BindingFrame bindings = func->upValues;
 2655|      0|                        bindings[func->params[0].id] = thunk;
 2656|      0|                        stack.newCall(ast.location, func, func->self, func->offset, bindings);
 2657|      0|                        ast_ = func->body;
 2658|      0|                        goto recurse;
 2659|      0|                    }
 2660|      0|                } break;
 2661|       |
 2662|  17.2M|                case FRAME_BUILTIN_FORCE_THUNKS: {
  ------------------
  |  Branch (2662:17): [True: 17.2M, False: 98.1M]
  ------------------
 2663|  17.2M|                    const auto &ast = *static_cast<const Apply *>(f.ast);
 2664|  17.2M|                    auto *func = static_cast<HeapClosure *>(f.val.v.h);
 2665|  17.2M|                    if (f.elementId == f.thunks.size()) {
  ------------------
  |  Branch (2665:25): [True: 6.70M, False: 10.5M]
  ------------------
 2666|       |                        // All thunks forced, now the builtin implementations.
 2667|  6.70M|                        const LocationRange &loc = ast.location;
 2668|  6.70M|                        const std::string &builtin_name = func->builtinName;
 2669|  6.70M|                        std::vector<Value> args;
 2670|  10.5M|                        for (auto *th : f.thunks) {
  ------------------
  |  Branch (2670:39): [True: 10.5M, False: 6.70M]
  ------------------
 2671|  10.5M|                            args.push_back(th->content);
 2672|  10.5M|                        }
 2673|  6.70M|                        BuiltinMap::const_iterator bit = builtins.find(builtin_name);
 2674|  6.70M|                        if (bit != builtins.end()) {
  ------------------
  |  Branch (2674:29): [True: 6.70M, False: 0]
  ------------------
 2675|  6.70M|                            const AST *new_ast = (this->*bit->second)(loc, args);
 2676|  6.70M|                            if (new_ast != nullptr) {
  ------------------
  |  Branch (2676:33): [True: 0, False: 6.70M]
  ------------------
 2677|      0|                                ast_ = new_ast;
 2678|      0|                                goto recurse;
 2679|      0|                            }
 2680|  6.70M|                            break;
 2681|  6.70M|                        }
 2682|      0|                        VmNativeCallbackMap::const_iterator nit =
 2683|      0|                            nativeCallbacks.find(builtin_name);
 2684|       |                        // TODO(dcunnin): Support arrays.
 2685|       |                        // TODO(dcunnin): Support objects.
 2686|      0|                        std::vector<JsonnetJsonValue> args2;
 2687|      0|                        for (const Value &arg : args) {
  ------------------
  |  Branch (2687:47): [True: 0, False: 0]
  ------------------
 2688|      0|                            switch (arg.t) {
 2689|      0|                                case Value::STRING:
  ------------------
  |  Branch (2689:33): [True: 0, False: 0]
  ------------------
 2690|      0|                                    args2.emplace_back(
 2691|      0|                                        JsonnetJsonValue::STRING,
 2692|      0|                                        encode_utf8(static_cast<HeapString *>(arg.v.h)->value),
 2693|      0|                                        0);
 2694|      0|                                    break;
 2695|       |
 2696|      0|                                case Value::BOOLEAN:
  ------------------
  |  Branch (2696:33): [True: 0, False: 0]
  ------------------
 2697|      0|                                    args2.emplace_back(
 2698|      0|                                        JsonnetJsonValue::BOOL, "", arg.v.b ? 1.0 : 0.0);
  ------------------
  |  Branch (2698:69): [True: 0, False: 0]
  ------------------
 2699|      0|                                    break;
 2700|       |
 2701|      0|                                case Value::NUMBER:
  ------------------
  |  Branch (2701:33): [True: 0, False: 0]
  ------------------
 2702|      0|                                    args2.emplace_back(JsonnetJsonValue::NUMBER, "", arg.v.d);
 2703|      0|                                    break;
 2704|       |
 2705|      0|                                case Value::NULL_TYPE:
  ------------------
  |  Branch (2705:33): [True: 0, False: 0]
  ------------------
 2706|      0|                                    args2.emplace_back(JsonnetJsonValue::NULL_KIND, "", 0);
 2707|      0|                                    break;
 2708|       |
 2709|      0|                                default:
  ------------------
  |  Branch (2709:33): [True: 0, False: 0]
  ------------------
 2710|      0|                                    throw makeError(ast.location,
 2711|      0|                                                    "native extensions can only take primitives.");
 2712|      0|                            }
 2713|      0|                        }
 2714|      0|                        std::vector<const JsonnetJsonValue *> args3;
 2715|      0|                        for (size_t i = 0; i < args2.size(); ++i) {
  ------------------
  |  Branch (2715:44): [True: 0, False: 0]
  ------------------
 2716|      0|                            args3.push_back(&args2[i]);
 2717|      0|                        }
 2718|      0|                        if (nit == nativeCallbacks.end()) {
  ------------------
  |  Branch (2718:29): [True: 0, False: 0]
  ------------------
 2719|      0|                            throw makeError(ast.location,
 2720|      0|                                            "unrecognized builtin name: " + builtin_name);
 2721|      0|                        }
 2722|      0|                        const VmNativeCallback &cb = nit->second;
 2723|       |
 2724|      0|                        int succ;
 2725|      0|                        std::unique_ptr<JsonnetJsonValue> r(cb.cb(cb.ctx, args3.data(), &succ));
 2726|       |
 2727|      0|                        if (succ) {
  ------------------
  |  Branch (2727:29): [True: 0, False: 0]
  ------------------
 2728|      0|                            bool unused;
 2729|      0|                            jsonToHeap(r, unused, scratch);
 2730|      0|                        } else {
 2731|      0|                            if (r->kind != JsonnetJsonValue::STRING) {
  ------------------
  |  Branch (2731:33): [True: 0, False: 0]
  ------------------
 2732|      0|                                throw makeError(
 2733|      0|                                    ast.location,
 2734|      0|                                    "native extension returned an error that was not a string.");
 2735|      0|                            }
 2736|      0|                            std::string rs = r->string;
 2737|      0|                            throw makeError(ast.location, rs);
 2738|      0|                        }
 2739|       |
 2740|  10.5M|                    } else {
 2741|       |                        // Not all arguments forced yet.
 2742|  10.5M|                        HeapThunk *th = f.thunks[f.elementId++];
 2743|  10.5M|                        if (!th->filled) {
  ------------------
  |  Branch (2743:29): [True: 10.5M, False: 0]
  ------------------
 2744|  10.5M|                            stack.newCall(ast.location, th, th->self, th->offset, th->upValues);
 2745|  10.5M|                            ast_ = th->body;
 2746|  10.5M|                            goto recurse;
 2747|  10.5M|                        }
 2748|  10.5M|                    }
 2749|  17.2M|                } break;
 2750|       |
 2751|  35.1M|                case FRAME_CALL: {
  ------------------
  |  Branch (2751:17): [True: 35.1M, False: 80.2M]
  ------------------
 2752|  35.1M|                    if (auto *thunk = dynamic_cast<HeapThunk *>(f.context)) {
  ------------------
  |  Branch (2752:31): [True: 18.9M, False: 16.2M]
  ------------------
 2753|       |                        // If we called a thunk, cache result.
 2754|  18.9M|                        thunk->fill(scratch);
 2755|  18.9M|                    } else if (auto *closure = dynamic_cast<HeapClosure *>(f.context)) {
  ------------------
  |  Branch (2755:38): [True: 5.74M, False: 10.4M]
  ------------------
 2756|  5.74M|                        if (f.elementId < f.thunks.size()) {
  ------------------
  |  Branch (2756:29): [True: 2.86M, False: 2.87M]
  ------------------
 2757|       |                            // If tailstrict, force thunks
 2758|  2.86M|                            HeapThunk *th = f.thunks[f.elementId++];
 2759|  2.86M|                            if (!th->filled) {
  ------------------
  |  Branch (2759:33): [True: 2.86M, False: 0]
  ------------------
 2760|  2.86M|                                stack.newCall(f.location, th, th->self, th->offset, th->upValues);
 2761|  2.86M|                                ast_ = th->body;
 2762|  2.86M|                                goto recurse;
 2763|  2.86M|                            }
 2764|  2.87M|                        } else if (f.thunks.size() == 0) {
  ------------------
  |  Branch (2764:36): [True: 1.62M, False: 1.25M]
  ------------------
 2765|       |                            // Body has now been executed
 2766|  1.62M|                        } else {
 2767|       |                            // Execute the body
 2768|  1.25M|                            f.thunks.clear();
 2769|  1.25M|                            f.elementId = 0;
 2770|  1.25M|                            ast_ = closure->body;
 2771|  1.25M|                            goto recurse;
 2772|  1.25M|                        }
 2773|  5.74M|                    }
 2774|       |                    // Result of call is in scratch, just pop.
 2775|  35.1M|                } break;
 2776|       |
 2777|  31.0M|                case FRAME_ERROR: {
  ------------------
  |  Branch (2777:17): [True: 2.47k, False: 115M]
  ------------------
 2778|  2.47k|                    const auto &ast = *static_cast<const Error *>(f.ast);
 2779|  2.47k|                    UString msg;
 2780|  2.47k|                    if (scratch.t == Value::STRING) {
  ------------------
  |  Branch (2780:25): [True: 413, False: 2.06k]
  ------------------
 2781|    413|                        msg = static_cast<HeapString *>(scratch.v.h)->value;
 2782|  2.06k|                    } else {
 2783|  2.06k|                        msg = toString(ast.location);
 2784|  2.06k|                    }
 2785|  2.47k|                    throw makeError(ast.location, encode_utf8(msg));
 2786|  35.1M|                } break;
 2787|       |
 2788|  6.37M|                case FRAME_IF: {
  ------------------
  |  Branch (2788:17): [True: 6.37M, False: 109M]
  ------------------
 2789|  6.37M|                    const auto &ast = *static_cast<const Conditional *>(f.ast);
 2790|  6.37M|                    if (scratch.t != Value::BOOLEAN) {
  ------------------
  |  Branch (2790:25): [True: 27, False: 6.37M]
  ------------------
 2791|     27|                        throw makeError(
 2792|     27|                            ast.location,
 2793|     27|                            "condition must be boolean, got " + type_str(scratch) + ".");
 2794|     27|                    }
 2795|  6.37M|                    ast_ = scratch.v.b ? ast.branchTrue : ast.branchFalse;
  ------------------
  |  Branch (2795:28): [True: 2.66M, False: 3.70M]
  ------------------
 2796|  6.37M|                    stack.pop();
 2797|  6.37M|                    goto recurse;
 2798|  6.37M|                } break;
 2799|       |
 2800|  2.05M|                case FRAME_SUPER_INDEX: {
  ------------------
  |  Branch (2800:17): [True: 2.05M, False: 113M]
  ------------------
 2801|  2.05M|                    const auto &ast = *static_cast<const SuperIndex *>(f.ast);
 2802|  2.05M|                    HeapObject *self;
 2803|  2.05M|                    unsigned offset;
 2804|  2.05M|                    stack.getSelfBinding(self, offset);
 2805|  2.05M|                    offset++;
 2806|  2.05M|                    if (offset >= countLeaves(self)) {
  ------------------
  |  Branch (2806:25): [True: 1, False: 2.05M]
  ------------------
 2807|      1|                        throw makeError(ast.location,
 2808|      1|                                        "attempt to use super when there is no super class.");
 2809|      1|                    }
 2810|  2.05M|                    if (scratch.t != Value::STRING) {
  ------------------
  |  Branch (2810:25): [True: 0, False: 2.05M]
  ------------------
 2811|      0|                        throw makeError(
 2812|      0|                            ast.location,
 2813|      0|                            "super index must be string, got " + type_str(scratch) + ".");
 2814|      0|                    }
 2815|       |
 2816|  2.05M|                    const UString &index_name = static_cast<HeapString *>(scratch.v.h)->value;
 2817|  2.05M|                    auto *fid = alloc->makeIdentifier(index_name);
 2818|  2.05M|                    stack.pop();
 2819|  2.05M|                    ast_ = objectIndex(ast.location, self, fid, offset);
 2820|  2.05M|                    goto recurse;
 2821|  2.05M|                } break;
 2822|       |
 2823|  2.24M|                case FRAME_IN_SUPER_ELEMENT: {
  ------------------
  |  Branch (2823:17): [True: 2.24M, False: 113M]
  ------------------
 2824|  2.24M|                    const auto &ast = *static_cast<const InSuper *>(f.ast);
 2825|  2.24M|                    HeapObject *self;
 2826|  2.24M|                    unsigned offset;
 2827|  2.24M|                    stack.getSelfBinding(self, offset);
 2828|  2.24M|                    offset++;
 2829|  2.24M|                    if (scratch.t != Value::STRING) {
  ------------------
  |  Branch (2829:25): [True: 1, False: 2.24M]
  ------------------
 2830|      1|                        throw makeError(ast.location,
 2831|      1|                                        "left hand side of e in super must be string, got " +
 2832|      1|                                            type_str(scratch) + ".");
 2833|      1|                    }
 2834|  2.24M|                    if (offset >= countLeaves(self)) {
  ------------------
  |  Branch (2834:25): [True: 78.3k, False: 2.17M]
  ------------------
 2835|       |                        // There is no super object.
 2836|  78.3k|                        scratch = makeBoolean(false);
 2837|  2.17M|                    } else {
 2838|  2.17M|                        const UString &element_name = static_cast<HeapString *>(scratch.v.h)->value;
 2839|  2.17M|                        auto *fid = alloc->makeIdentifier(element_name);
 2840|  2.17M|                        unsigned unused_found_at = 0;
 2841|  2.17M|                        bool in = findObject(fid, self, offset, unused_found_at);
 2842|  2.17M|                        scratch = makeBoolean(in);
 2843|  2.17M|                    }
 2844|  2.24M|                } break;
 2845|       |
 2846|  8.83M|                case FRAME_INDEX_INDEX: {
  ------------------
  |  Branch (2846:17): [True: 8.83M, False: 106M]
  ------------------
 2847|  8.83M|                    const auto &ast = *static_cast<const Index *>(f.ast);
 2848|  8.83M|                    const Value &target = f.val;
 2849|  8.83M|                    if (target.t == Value::ARRAY) {
  ------------------
  |  Branch (2849:25): [True: 125k, False: 8.71M]
  ------------------
 2850|   125k|                        const auto *array = static_cast<HeapArray *>(target.v.h);
 2851|   125k|                        if (scratch.t == Value::STRING) {
  ------------------
  |  Branch (2851:29): [True: 60, False: 125k]
  ------------------
 2852|     60|                            const UString &str = static_cast<HeapString *>(scratch.v.h)->value;
 2853|     60|                            throw makeError(
 2854|     60|                                ast.location,
 2855|     60|                                "attempted index an array with string \""
 2856|     60|                                + encode_utf8(jsonnet_string_escape(str, false)) + "\".");
 2857|     60|                        }
 2858|   125k|                        if (scratch.t != Value::NUMBER) {
  ------------------
  |  Branch (2858:29): [True: 7, False: 125k]
  ------------------
 2859|      7|                            throw makeError(
 2860|      7|                                ast.location,
 2861|      7|                                "array index must be number, got " + type_str(scratch) + ".");
 2862|      7|                        }
 2863|   125k|                        double index = ::floor(scratch.v.d);
 2864|   125k|                        long sz = array->elements.size();
 2865|   125k|                        if (index < 0 || index >= sz) {
  ------------------
  |  Branch (2865:29): [True: 3, False: 125k]
  |  Branch (2865:42): [True: 2, False: 125k]
  ------------------
 2866|      5|                            std::stringstream ss;
 2867|      5|                            ss << "array bounds error: " << index << " not within [0, " << sz
 2868|      5|                               << ")";
 2869|      5|                            throw makeError(ast.location, ss.str());
 2870|      5|                        }
 2871|   125k|                        if (scratch.v.d != index) {
  ------------------
  |  Branch (2871:29): [True: 13, False: 125k]
  ------------------
 2872|     13|                            std::stringstream ss;
 2873|     13|                            ss << "array index was not integer: " << scratch.v.d;
 2874|     13|                            throw makeError(ast.location, ss.str());
 2875|     13|                        }
 2876|       |                        // index < sz <= SIZE_T_MAX
 2877|   125k|                        auto *thunk = array->elements[size_t(index)];
 2878|   125k|                        if (thunk->filled) {
  ------------------
  |  Branch (2878:29): [True: 114k, False: 10.9k]
  ------------------
 2879|   114k|                            scratch = thunk->content;
 2880|   114k|                        } else {
 2881|  10.9k|                            stack.pop();
 2882|  10.9k|                            stack.newCall(
 2883|  10.9k|                                ast.location, thunk, thunk->self, thunk->offset, thunk->upValues);
 2884|  10.9k|                            ast_ = thunk->body;
 2885|  10.9k|                            goto recurse;
 2886|  10.9k|                        }
 2887|  8.71M|                    } else if (target.t == Value::OBJECT) {
  ------------------
  |  Branch (2887:32): [True: 8.51M, False: 198k]
  ------------------
 2888|  8.51M|                        auto *obj = static_cast<HeapObject *>(target.v.h);
 2889|  8.51M|                        assert(obj != nullptr);
 2890|  8.51M|                        if (scratch.t != Value::STRING) {
  ------------------
  |  Branch (2890:29): [True: 8, False: 8.51M]
  ------------------
 2891|      8|                            throw makeError(
 2892|      8|                                ast.location,
 2893|      8|                                "object index must be string, got " + type_str(scratch) + ".");
 2894|      8|                        }
 2895|  8.51M|                        const UString &index_name = static_cast<HeapString *>(scratch.v.h)->value;
 2896|  8.51M|                        auto *fid = alloc->makeIdentifier(index_name);
 2897|  8.51M|                        stack.pop();
 2898|  8.51M|                        ast_ = objectIndex(ast.location, obj, fid, 0);
 2899|  8.51M|                        goto recurse;
 2900|  8.51M|                    } else if (target.t == Value::STRING) {
  ------------------
  |  Branch (2900:32): [True: 198k, False: 0]
  ------------------
 2901|   198k|                        auto *obj = static_cast<HeapString *>(target.v.h);
 2902|   198k|                        assert(obj != nullptr);
 2903|   198k|                        if (scratch.t != Value::NUMBER) {
  ------------------
  |  Branch (2903:29): [True: 9, False: 198k]
  ------------------
 2904|      9|                            throw makeError(
 2905|      9|                                ast.location,
 2906|      9|                                "string index must be a number, got " + type_str(scratch) + ".");
 2907|      9|                        }
 2908|   198k|                        long sz = obj->value.length();
 2909|   198k|                        long i = (long)scratch.v.d;
 2910|   198k|                        if (i < 0 || i >= sz) {
  ------------------
  |  Branch (2910:29): [True: 70, False: 198k]
  |  Branch (2910:38): [True: 52, False: 198k]
  ------------------
 2911|    122|                            std::stringstream ss;
 2912|    122|                            ss << "string bounds error: " << i << " not within [0, " << sz << ")";
 2913|    122|                            throw makeError(ast.location, ss.str());
 2914|    122|                        }
 2915|   198k|                        char32_t ch[] = {obj->value[i], U'\0'};
 2916|   198k|                        scratch = makeString(ch);
 2917|   198k|                    } else {
 2918|      0|                        std::cerr << "INTERNAL ERROR: not object / array / string." << std::endl;
 2919|      0|                        abort();
 2920|      0|                    }
 2921|  8.83M|                } break;
 2922|       |
 2923|  8.83M|                case FRAME_INDEX_TARGET: {
  ------------------
  |  Branch (2923:17): [True: 8.83M, False: 106M]
  ------------------
 2924|  8.83M|                    const auto &ast = *static_cast<const Index *>(f.ast);
 2925|  8.83M|                    if (scratch.t != Value::ARRAY && scratch.t != Value::OBJECT &&
  ------------------
  |  Branch (2925:25): [True: 8.71M, False: 125k]
  |  Branch (2925:54): [True: 198k, False: 8.51M]
  ------------------
 2926|  8.83M|                        scratch.t != Value::STRING) {
  ------------------
  |  Branch (2926:25): [True: 12, False: 198k]
  ------------------
 2927|     12|                        throw makeError(ast.location,
 2928|     12|                                        "can only index objects, strings, and arrays, got " +
 2929|     12|                                            type_str(scratch) + ".");
 2930|     12|                    }
 2931|  8.83M|                    f.val = scratch;
 2932|  8.83M|                    f.kind = FRAME_INDEX_INDEX;
 2933|  8.83M|                    if (scratch.t == Value::OBJECT) {
  ------------------
  |  Branch (2933:25): [True: 8.51M, False: 323k]
  ------------------
 2934|  8.51M|                        auto *self = static_cast<HeapObject *>(scratch.v.h);
 2935|  8.51M|                        if (!stack.alreadyExecutingInvariants(self)) {
  ------------------
  |  Branch (2935:29): [True: 8.51M, False: 0]
  ------------------
 2936|  8.51M|                            stack.newFrame(FRAME_INVARIANTS, ast.location);
 2937|  8.51M|                            Frame &f2 = stack.top();
 2938|  8.51M|                            f2.self = self;
 2939|  8.51M|                            unsigned counter = 0;
 2940|  8.51M|                            objectInvariants(self, self, counter, f2.thunks);
 2941|  8.51M|                            if (f2.thunks.size() > 0) {
  ------------------
  |  Branch (2941:33): [True: 546, False: 8.51M]
  ------------------
 2942|    546|                                auto *thunk = f2.thunks[0];
 2943|    546|                                f2.elementId = 1;
 2944|    546|                                stack.newCall(ast.location,
 2945|    546|                                              thunk,
 2946|    546|                                              thunk->self,
 2947|    546|                                              thunk->offset,
 2948|    546|                                              thunk->upValues);
 2949|    546|                                ast_ = thunk->body;
 2950|    546|                                goto recurse;
 2951|    546|                            }
 2952|  8.51M|                        }
 2953|  8.51M|                    }
 2954|  8.83M|                    ast_ = ast.index;
 2955|  8.83M|                    goto recurse;
 2956|  8.83M|                } break;
 2957|       |
 2958|  8.55M|                case FRAME_INVARIANTS: {
  ------------------
  |  Branch (2958:17): [True: 8.55M, False: 106M]
  ------------------
 2959|  8.55M|                    if (f.elementId >= f.thunks.size()) {
  ------------------
  |  Branch (2959:25): [True: 8.52M, False: 29.9k]
  ------------------
 2960|  8.52M|                        if (stack.size() == initial_stack_size + 1) {
  ------------------
  |  Branch (2960:29): [True: 16.2k, False: 8.51M]
  ------------------
 2961|       |                            // Just pop, evaluate was invoked by runInvariants.
 2962|  16.2k|                            break;
 2963|  16.2k|                        }
 2964|  8.51M|                        stack.pop();
 2965|  8.51M|                        Frame &f2 = stack.top();
 2966|  8.51M|                        const auto &ast = *static_cast<const Index *>(f2.ast);
 2967|  8.51M|                        ast_ = ast.index;
 2968|  8.51M|                        goto recurse;
 2969|  8.52M|                    }
 2970|  29.9k|                    auto *thunk = f.thunks[f.elementId++];
 2971|  29.9k|                    stack.newCall(f.location, thunk, thunk->self, thunk->offset, thunk->upValues);
 2972|  29.9k|                    ast_ = thunk->body;
 2973|  29.9k|                    goto recurse;
 2974|  8.55M|                } break;
 2975|       |
 2976|  3.82M|                case FRAME_LOCAL: {
  ------------------
  |  Branch (2976:17): [True: 3.82M, False: 111M]
  ------------------
 2977|       |                    // Result of execution is in scratch already.
 2978|  3.82M|                } break;
 2979|       |
 2980|  1.85M|                case FRAME_OBJECT: {
  ------------------
  |  Branch (2980:17): [True: 1.85M, False: 113M]
  ------------------
 2981|  1.85M|                    const auto &ast = *static_cast<const DesugaredObject *>(f.ast);
 2982|  1.85M|                    if (scratch.t != Value::NULL_TYPE) {
  ------------------
  |  Branch (2982:25): [True: 1.85M, False: 0]
  ------------------
 2983|  1.85M|                        if (scratch.t != Value::STRING) {
  ------------------
  |  Branch (2983:29): [True: 11, False: 1.85M]
  ------------------
 2984|     11|                            throw makeError(ast.location, "field name was not a string.");
 2985|     11|                        }
 2986|  1.85M|                        const auto &fname = static_cast<const HeapString *>(scratch.v.h)->value;
 2987|  1.85M|                        const Identifier *fid = alloc->makeIdentifier(fname);
 2988|  1.85M|                        if (f.objectFields.find(fid) != f.objectFields.end()) {
  ------------------
  |  Branch (2988:29): [True: 9, False: 1.85M]
  ------------------
 2989|      9|                            std::string msg =
 2990|      9|                                "duplicate field name: \"" + encode_utf8(fname) + "\"";
 2991|      9|                            throw makeError(ast.location, msg);
 2992|      9|                        }
 2993|  1.85M|                        f.objectFields[fid].hide = f.fit->hide;
 2994|  1.85M|                        f.objectFields[fid].body = f.fit->body;
 2995|  1.85M|                    }
 2996|  1.85M|                    f.fit++;
 2997|  1.85M|                    if (f.fit != ast.fields.end()) {
  ------------------
  |  Branch (2997:25): [True: 1.44M, False: 416k]
  ------------------
 2998|  1.44M|                        ast_ = f.fit->name;
 2999|  1.44M|                        goto recurse;
 3000|  1.44M|                    } else {
 3001|   416k|                        auto env = capture(ast.freeVariables);
 3002|   416k|                        scratch = makeObject<HeapSimpleObject>(env, f.objectFields, ast.asserts);
 3003|   416k|                    }
 3004|  1.85M|                } break;
 3005|       |
 3006|   416k|                case FRAME_OBJECT_COMP_ARRAY: {
  ------------------
  |  Branch (3006:17): [True: 0, False: 115M]
  ------------------
 3007|      0|                    const auto &ast = *static_cast<const ObjectComprehensionSimple *>(f.ast);
 3008|      0|                    const Value &arr_v = scratch;
 3009|      0|                    if (scratch.t != Value::ARRAY) {
  ------------------
  |  Branch (3009:25): [True: 0, False: 0]
  ------------------
 3010|      0|                        throw makeError(ast.location,
 3011|      0|                                        "object comprehension needs array, got " + type_str(arr_v));
 3012|      0|                    }
 3013|      0|                    const auto *arr = static_cast<const HeapArray *>(arr_v.v.h);
 3014|      0|                    if (arr->elements.size() == 0) {
  ------------------
  |  Branch (3014:25): [True: 0, False: 0]
  ------------------
 3015|       |                        // Degenerate case.  Just create the object now.
 3016|      0|                        scratch = makeObject<HeapComprehensionObject>(
 3017|      0|                            BindingFrame{}, ast.value, ast.id, BindingFrame{});
 3018|      0|                    } else {
 3019|      0|                        f.kind = FRAME_OBJECT_COMP_ELEMENT;
 3020|      0|                        f.val = scratch;
 3021|      0|                        f.bindings[ast.id] = arr->elements[0];
 3022|      0|                        f.elementId = 0;
 3023|      0|                        ast_ = ast.field;
 3024|      0|                        goto recurse;
 3025|      0|                    }
 3026|      0|                } break;
 3027|       |
 3028|      0|                case FRAME_OBJECT_COMP_ELEMENT: {
  ------------------
  |  Branch (3028:17): [True: 0, False: 115M]
  ------------------
 3029|      0|                    const auto &ast = *static_cast<const ObjectComprehensionSimple *>(f.ast);
 3030|      0|                    const auto *arr = static_cast<const HeapArray *>(f.val.v.h);
 3031|      0|                    if (scratch.t != Value::NULL_TYPE) {
  ------------------
  |  Branch (3031:25): [True: 0, False: 0]
  ------------------
 3032|      0|                        if (scratch.t != Value::STRING) {
  ------------------
  |  Branch (3032:29): [True: 0, False: 0]
  ------------------
 3033|      0|                            std::stringstream ss;
 3034|      0|                            ss << "field must be string, got: " << type_str(scratch);
 3035|      0|                            throw makeError(ast.location, ss.str());
 3036|      0|                        }
 3037|      0|                        const auto &fname = static_cast<const HeapString *>(scratch.v.h)->value;
 3038|      0|                        const Identifier *fid = alloc->makeIdentifier(fname);
 3039|      0|                        if (f.elements.find(fid) != f.elements.end()) {
  ------------------
  |  Branch (3039:29): [True: 0, False: 0]
  ------------------
 3040|      0|                            throw makeError(ast.location,
 3041|      0|                                            "duplicate field name: \"" + encode_utf8(fname) + "\"");
 3042|      0|                        }
 3043|      0|                        f.elements[fid] = arr->elements[f.elementId];
 3044|      0|                    }
 3045|      0|                    f.elementId++;
 3046|       |
 3047|      0|                    if (f.elementId == arr->elements.size()) {
  ------------------
  |  Branch (3047:25): [True: 0, False: 0]
  ------------------
 3048|      0|                        auto env = capture(ast.freeVariables);
 3049|      0|                        scratch =
 3050|      0|                            makeObject<HeapComprehensionObject>(env, ast.value, ast.id, f.elements);
 3051|      0|                    } else {
 3052|      0|                        f.bindings[ast.id] = arr->elements[f.elementId];
 3053|      0|                        ast_ = ast.field;
 3054|      0|                        goto recurse;
 3055|      0|                    }
 3056|      0|                } break;
 3057|       |
 3058|  1.79M|                case FRAME_STRING_CONCAT: {
  ------------------
  |  Branch (3058:17): [True: 1.79M, False: 113M]
  ------------------
 3059|  1.79M|                    const auto &ast = *static_cast<const Binary *>(f.ast);
 3060|  1.79M|                    const Value &lhs = stack.top().val;
 3061|  1.79M|                    UString output;
 3062|  1.79M|                    if (lhs.t == Value::STRING) {
  ------------------
  |  Branch (3062:25): [True: 1.65M, False: 140k]
  ------------------
 3063|  1.65M|                        output.append(static_cast<const HeapString *>(lhs.v.h)->value);
 3064|  1.65M|                    } else {
 3065|   140k|                        scratch = lhs;
 3066|   140k|                        output.append(toString(ast.left->location));
 3067|   140k|                    }
 3068|  1.79M|                    const Value &rhs = stack.top().val2;
 3069|  1.79M|                    if (rhs.t == Value::STRING) {
  ------------------
  |  Branch (3069:25): [True: 1.63M, False: 158k]
  ------------------
 3070|  1.63M|                        output.append(static_cast<const HeapString *>(rhs.v.h)->value);
 3071|  1.63M|                    } else {
 3072|   158k|                        scratch = rhs;
 3073|   158k|                        output.append(toString(ast.right->location));
 3074|   158k|                    }
 3075|  1.79M|                    scratch = makeString(output);
 3076|  1.79M|                } break;
 3077|       |
 3078|  1.34M|                case FRAME_UNARY: {
  ------------------
  |  Branch (3078:17): [True: 1.34M, False: 114M]
  ------------------
 3079|  1.34M|                    const auto &ast = *static_cast<const Unary *>(f.ast);
 3080|  1.34M|                    switch (scratch.t) {
 3081|  1.30M|                        case Value::BOOLEAN:
  ------------------
  |  Branch (3081:25): [True: 1.30M, False: 43.2k]
  ------------------
 3082|  1.30M|                            if (ast.op == UOP_NOT) {
  ------------------
  |  Branch (3082:33): [True: 1.30M, False: 2]
  ------------------
 3083|  1.30M|                                scratch = makeBoolean(!scratch.v.b);
 3084|  1.30M|                            } else {
 3085|      2|                                throw makeError(ast.location,
 3086|      2|                                                "unary operator " + uop_string(ast.op) +
 3087|      2|                                                    " does not operate on booleans.");
 3088|      2|                            }
 3089|  1.30M|                            break;
 3090|       |
 3091|  1.30M|                        case Value::NUMBER:
  ------------------
  |  Branch (3091:25): [True: 43.2k, False: 1.30M]
  ------------------
 3092|  43.2k|                            switch (ast.op) {
 3093|  1.61k|                                case UOP_PLUS: break;
  ------------------
  |  Branch (3093:33): [True: 1.61k, False: 41.5k]
  ------------------
 3094|       |
 3095|  40.4k|                                case UOP_MINUS: scratch = makeNumber(-scratch.v.d); break;
  ------------------
  |  Branch (3095:33): [True: 40.4k, False: 2.72k]
  ------------------
 3096|       |
 3097|  1.09k|                                case UOP_BITWISE_NOT:
  ------------------
  |  Branch (3097:33): [True: 1.09k, False: 42.1k]
  ------------------
 3098|  1.09k|                                    scratch = makeNumber(~(long)(scratch.v.d));
 3099|  1.09k|                                    break;
 3100|       |
 3101|     18|                                default:
  ------------------
  |  Branch (3101:33): [True: 18, False: 43.1k]
  ------------------
 3102|     18|                                    throw makeError(ast.location,
 3103|     18|                                                    "unary operator " + uop_string(ast.op) +
 3104|     18|                                                        " does not operate on numbers.");
 3105|  43.2k|                            }
 3106|  43.1k|                            break;
 3107|       |
 3108|  43.1k|                        default:
  ------------------
  |  Branch (3108:25): [True: 66, False: 1.34M]
  ------------------
 3109|     66|                            throw makeError(ast.location,
 3110|     66|                                            "unary operator " + uop_string(ast.op) +
 3111|     66|                                                " does not operate on type " + type_str(scratch));
 3112|  1.34M|                    }
 3113|  1.34M|                } break;
 3114|       |
 3115|  1.34M|                case FRAME_BUILTIN_JOIN_STRINGS: {
  ------------------
  |  Branch (3115:17): [True: 0, False: 115M]
  ------------------
 3116|      0|                    joinString(f.first, f.str, f.val, f.elementId, scratch);
 3117|      0|                    f.elementId++;
 3118|      0|                    auto *ast = joinStrings();
 3119|      0|                    if (ast != nullptr) {
  ------------------
  |  Branch (3119:25): [True: 0, False: 0]
  ------------------
 3120|      0|                        ast_ = ast;
 3121|      0|                        goto recurse;
 3122|      0|                    }
 3123|      0|                } break;
 3124|       |
 3125|      0|                case FRAME_BUILTIN_JOIN_ARRAYS: {
  ------------------
  |  Branch (3125:17): [True: 0, False: 115M]
  ------------------
 3126|      0|                    joinArray(f.first, f.thunks, f.val, f.elementId, scratch);
 3127|      0|                    f.elementId++;
 3128|      0|                    auto *ast = joinArrays();
 3129|      0|                    if (ast != nullptr) {
  ------------------
  |  Branch (3129:25): [True: 0, False: 0]
  ------------------
 3130|      0|                        ast_ = ast;
 3131|      0|                        goto recurse;
 3132|      0|                    }
 3133|      0|                } break;
 3134|       |
 3135|      0|                 case FRAME_BUILTIN_DECODE_UTF8: {
  ------------------
  |  Branch (3135:18): [True: 0, False: 115M]
  ------------------
 3136|      0|                    auto *ast = decodeUTF8();
 3137|      0|                    if (ast != nullptr) {
  ------------------
  |  Branch (3137:25): [True: 0, False: 0]
  ------------------
 3138|      0|                        ast_ = ast;
 3139|      0|                        goto recurse;
 3140|      0|                    }
 3141|      0|                } break;
 3142|       |
 3143|      0|                default:
  ------------------
  |  Branch (3143:17): [True: 0, False: 115M]
  ------------------
 3144|      0|                    std::cerr << "INTERNAL ERROR: Unknown FrameKind:  " << f.kind << std::endl;
 3145|      0|                    std::abort();
 3146|   115M|            }
 3147|       |
 3148|  50.1M|        popframe:;
 3149|       |
 3150|  50.1M|            stack.pop();
 3151|       |
 3152|  59.9M|        replaceframe:;
 3153|  59.9M|        }
 3154|  57.8M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack8newFrameIJNS1_9FrameKindEPKNS0_3ASTEEEEvDpT_:
  378|  46.0M|    {
  379|  46.0M|        stack.emplace_back(args...);
  380|  46.0M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15FrameC2ERKNS1_9FrameKindEPKNS0_3ASTE:
  194|  46.0M|    {
  195|  46.0M|        val.t = Value::NULL_TYPE;
  196|  46.0M|        val2.t = Value::NULL_TYPE;
  197|  46.0M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack14getSelfBindingERPNS1_10HeapObjectERj:
  434|  27.5M|    {
  435|  27.5M|        self = nullptr;
  436|  27.5M|        offset = 0;
  437|  90.0M|        for (int i = stack.size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (437:40): [True: 90.0M, False: 16.6k]
  ------------------
  438|  90.0M|            if (stack[i].isCall()) {
  ------------------
  |  Branch (438:17): [True: 27.5M, False: 62.4M]
  ------------------
  439|  27.5M|                self = stack[i].self;
  440|  27.5M|                offset = stack[i].offset;
  441|  27.5M|                return;
  442|  27.5M|            }
  443|  90.0M|        }
  444|  27.5M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPNS0_3ASTEEEEPT_DpOT0_:
  567|  20.8M|    {
  568|  20.8M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|  20.8M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 20.4k, False: 20.8M]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|  20.4k|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|  20.4k|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|  20.4k|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|  20.4k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 20.4k]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|  3.12M|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 3.12M, False: 20.4k]
  ------------------
  587|  3.12M|                heap.markFrom(sourceVal.second);
  588|  3.12M|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|  20.4k|            heap.sweep();
  592|  20.4k|        }
  593|  20.8M|        return r;
  594|  20.8M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter7captureERKNSt3__16vectorIPKNS0_10IdentifierENS3_9allocatorIS7_EEEE:
  840|  39.7M|    {
  841|  39.7M|        BindingFrame env;
  842|   533M|        for (auto fv : free_vars) {
  ------------------
  |  Branch (842:22): [True: 533M, False: 39.7M]
  ------------------
  843|   533M|            auto *th = stack.lookUpVar(fv);
  844|   533M|            env[fv] = th;
  845|   533M|        }
  846|  39.7M|        return env;
  847|  39.7M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11makeClosureERKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS3_4lessIS7_EENS3_9allocatorINS3_4pairIKS7_S9_EEEEEEPNS1_10HeapObjectEjRKNS3_6vectorINS1_11HeapClosure5ParamENSC_ISO_EEEEPNS0_3ASTE:
  640|  1.68M|    {
  641|  1.68M|        Value r;
  642|  1.68M|        r.t = Value::FUNCTION;
  643|  1.68M|        r.v.h = makeHeap<HeapClosure>(env, self, offset, params, body, "");
  644|  1.68M|        return r;
  645|  1.68M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_11HeapClosureEJRKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEERPNS1_10HeapObjectERjRKNS5_6vectorINS4_5ParamENSE_ISR_EEEERPNS0_3ASTERA1_KcEEEPT_DpOT0_:
  567|  1.68M|    {
  568|  1.68M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|  1.68M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 2.37k, False: 1.67M]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|  2.37k|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|  2.37k|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|  2.37k|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|  2.37k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 2.37k]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|   362k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 362k, False: 2.37k]
  ------------------
  587|   362k|                heap.markFrom(sourceVal.second);
  588|   362k|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|  2.37k|            heap.sweep();
  592|  2.37k|        }
  593|  1.68M|        return r;
  594|  1.68M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter6importERKNS0_13LocationRangeEPKNS0_13LiteralStringE:
  775|     89|    {
  776|     89|        ImportCacheValue *input = importData(loc, file);
  777|     89|        if (input->thunk == nullptr) {
  ------------------
  |  Branch (777:13): [True: 0, False: 89]
  ------------------
  778|      0|            Tokens tokens = jsonnet_lex(input->foundHere, input->content.c_str());
  779|      0|            AST *expr = jsonnet_parse(alloc, tokens);
  780|      0|            jsonnet_desugar(alloc, expr, nullptr);
  781|      0|            jsonnet_static_analysis(expr);
  782|       |            // If no errors then populate cache.
  783|      0|            auto *thunk = makeHeap<HeapThunk>(idImport, nullptr, 0, expr);
  784|      0|            input->thunk = thunk;
  785|      0|        }
  786|     89|        return input->thunk;
  787|     89|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10importDataERKNS0_13LocationRangeEPKNS0_13LiteralStringE:
  799|    105|    {
  800|    105|        std::string dir = dir_name(loc.file);
  801|       |
  802|    105|        const UString &path = file->value;
  803|       |
  804|    105|        std::pair<std::string, UString> key(dir, path);
  805|    105|        ImportCacheValue *cached_value = cachedImports[key];
  806|    105|        if (cached_value != nullptr)
  ------------------
  |  Branch (806:13): [True: 0, False: 105]
  ------------------
  807|      0|            return cached_value;
  808|       |
  809|    105|        char *found_here_cptr;
  810|    105|        char *buf = NULL;
  811|    105|        size_t buflen = 0;
  812|    105|        int result = importCallback(importCallbackContext,
  813|    105|                                    dir.c_str(),
  814|    105|                                    encode_utf8(path).c_str(),
  815|    105|                                    &found_here_cptr,
  816|    105|                                    &buf,
  817|    105|                                    &buflen);
  818|       |
  819|    105|        std::string input(buf, buflen);
  820|    105|        ::free(buf);
  821|       |
  822|    105|        if (result == 1) {  // failure
  ------------------
  |  Branch (822:13): [True: 105, False: 0]
  ------------------
  823|    105|            std::string epath = encode_utf8(jsonnet_string_escape(path, false));
  824|    105|            std::string msg = "couldn't open import \"" + epath + "\": ";
  825|    105|            msg += input;
  826|    105|            throw makeError(loc, msg);
  827|    105|        }
  828|       |
  829|      0|        auto *input_ptr = new ImportCacheValue();
  830|      0|        input_ptr->foundHere = found_here_cptr;
  831|      0|        input_ptr->content = input;
  832|      0|        input_ptr->thunk = nullptr;  // May be filled in later by import().
  833|      0|        ::free(found_here_cptr);
  834|      0|        cachedImports[key] = input_ptr;
  835|      0|        return input_ptr;
  836|    105|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_18dir_nameERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   57|    105|{
   58|    105|    size_t last_slash = path.rfind('/');
   59|    105|    if (last_slash != std::string::npos) {
  ------------------
  |  Branch (59:9): [True: 0, False: 105]
  ------------------
   60|      0|        return path.substr(0, last_slash + 1);
   61|      0|    }
   62|    105|    return "";
   63|    105|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJRKPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPNS0_3ASTEEEEPT_DpOT0_:
  567|  15.1M|    {
  568|  15.1M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|  15.1M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 16.5k, False: 15.1M]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|  16.5k|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|  16.5k|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|  16.5k|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|  16.5k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 16.5k]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|  2.52M|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 2.52M, False: 16.5k]
  ------------------
  587|  2.52M|                heap.markFrom(sourceVal.second);
  588|  2.52M|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|  16.5k|            heap.sweep();
  592|  16.5k|        }
  593|  15.1M|        return r;
  594|  15.1M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10makeObjectINS1_16HeapSimpleObjectEJNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEENS6_IS9_NS4_5FieldESD_NSE_INSF_ISG_SK_EEEEEENS5_4listIPNS0_3ASTENSE_ISQ_EEEEEEENS1_5ValueEDpT0_:
  667|  1.58M|    {
  668|  1.58M|        Value r;
  669|  1.58M|        r.t = Value::OBJECT;
  670|  1.58M|        r.v.h = makeHeap<T>(args...);
  671|  1.58M|        return r;
  672|  1.58M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_16HeapSimpleObjectEJRNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEERNS6_IS9_NS4_5FieldESD_NSE_INSF_ISG_SL_EEEEEERNS5_4listIPNS0_3ASTENSE_ISS_EEEEEEEPT_DpOT0_:
  567|  1.58M|    {
  568|  1.58M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|  1.58M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 1.81k, False: 1.58M]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|  1.81k|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|  1.81k|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|  1.81k|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|  1.81k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 1.81k]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|   277k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 277k, False: 1.81k]
  ------------------
  587|   277k|                heap.markFrom(sourceVal.second);
  588|   277k|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|  1.81k|            heap.sweep();
  592|  1.81k|        }
  593|  1.58M|        return r;
  594|  1.58M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack9lookUpVarEPKNS0_10IdentifierE:
  259|   554M|    {
  260|   632M|        for (int i = stack.size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (260:40): [True: 632M, False: 0]
  ------------------
  261|   632M|            const auto &binds = stack[i].bindings;
  262|   632M|            auto it = binds.find(id);
  263|   632M|            if (it != binds.end()) {
  ------------------
  |  Branch (263:17): [True: 554M, False: 77.2M]
  ------------------
  264|   554M|                return it->second;
  265|   554M|            }
  266|  77.2M|            if (stack[i].isCall())
  ------------------
  |  Branch (266:17): [True: 0, False: 77.2M]
  ------------------
  267|      0|                break;
  268|  77.2M|        }
  269|      0|        return nullptr;
  270|   554M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack4sizeEv:
  253|   129M|    {
  254|   129M|        return stack.size();
  255|   129M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPKNS0_3ASTEEEEPT_DpOT0_:
  567|     37|    {
  568|     37|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|     37|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 0, False: 37]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|      0|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|      0|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|      0|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|      0|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 0]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|      0|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 0, False: 0]
  ------------------
  587|      0|                heap.markFrom(sourceVal.second);
  588|      0|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|      0|            heap.sweep();
  592|      0|        }
  593|     37|        return r;
  594|     37|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10findObjectEPKNS0_10IdentifierEPNS1_10HeapObjectEjRj:
  694|  1.18G|    {
  695|  1.18G|        if (auto *ext = dynamic_cast<HeapExtendedObject *>(curr)) {
  ------------------
  |  Branch (695:19): [True: 589M, False: 597M]
  ------------------
  696|   589M|            auto *r = findObject(f, ext->right, start_from, counter);
  697|   589M|            if (r)
  ------------------
  |  Branch (697:17): [True: 5.23M, False: 584M]
  ------------------
  698|  5.23M|                return r;
  699|   584M|            auto *l = findObject(f, ext->left, start_from, counter);
  700|   584M|            if (l)
  ------------------
  |  Branch (700:17): [True: 416M, False: 167M]
  ------------------
  701|   416M|                return l;
  702|   597M|        } else {
  703|   597M|            if (counter >= start_from) {
  ------------------
  |  Branch (703:17): [True: 30.3M, False: 567M]
  ------------------
  704|  30.3M|                if (auto *simp = dynamic_cast<HeapSimpleObject *>(curr)) {
  ------------------
  |  Branch (704:27): [True: 30.3M, False: 0]
  ------------------
  705|  30.3M|                    auto it = simp->fields.find(f);
  706|  30.3M|                    if (it != simp->fields.end()) {
  ------------------
  |  Branch (706:25): [True: 13.1M, False: 17.1M]
  ------------------
  707|  13.1M|                        return simp;
  708|  13.1M|                    }
  709|  30.3M|                } else if (auto *comp = dynamic_cast<HeapComprehensionObject *>(curr)) {
  ------------------
  |  Branch (709:34): [True: 0, False: 0]
  ------------------
  710|      0|                    auto it = comp->compValues.find(f);
  711|      0|                    if (it != comp->compValues.end()) {
  ------------------
  |  Branch (711:25): [True: 0, False: 0]
  ------------------
  712|      0|                        return comp;
  713|      0|                    }
  714|      0|                }
  715|  30.3M|            }
  716|   584M|            counter++;
  717|   584M|        }
  718|   752M|        return nullptr;
  719|  1.18G|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13callSourceValEPKNS0_3ASTEPNS1_9HeapThunkENSt3__16vectorIS7_NS8_9allocatorIS7_EEEE:
 1963|  9.75k|    const AST *callSourceVal(const AST *ast, HeapThunk *sourceVal, std::vector<HeapThunk*> args) {
 1964|  9.75k|        assert(sourceVal != nullptr);
 1965|      0|        assert(sourceVal->filled);
 1966|      0|        assert(sourceVal->content.t == Value::FUNCTION);
 1967|      0|        auto *func = static_cast<HeapClosure *>(sourceVal->content.v.h);
 1968|  9.75k|        BindingFrame up_values = func->upValues;
 1969|  29.2k|        for (size_t i = 0; i < args.size(); ++i) {
  ------------------
  |  Branch (1969:28): [True: 19.5k, False: 9.75k]
  ------------------
 1970|  19.5k|            up_values.insert({func->params[i].id, args[i]});
 1971|  19.5k|        }
 1972|  9.75k|        stack.newCall(ast->location, func, func->self, func->offset, up_values);
 1973|  9.75k|        return func->body;
 1974|  9.75k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10makeObjectINS1_18HeapExtendedObjectEJPNS1_10HeapObjectES6_EEENS1_5ValueEDpT0_:
  667|   954k|    {
  668|   954k|        Value r;
  669|   954k|        r.t = Value::OBJECT;
  670|   954k|        r.v.h = makeHeap<T>(args...);
  671|   954k|        return r;
  672|   954k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_18HeapExtendedObjectEJRPNS1_10HeapObjectES7_EEEPT_DpOT0_:
  567|   954k|    {
  568|   954k|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|   954k|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 1.01k, False: 953k]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|  1.01k|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|  1.01k|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|  1.01k|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|  1.01k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 1.01k]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|   155k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 155k, False: 1.01k]
  ------------------
  587|   155k|                heap.markFrom(sourceVal.second);
  588|   155k|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|  1.01k|            heap.sweep();
  592|  1.01k|        }
  593|   954k|        return r;
  594|   954k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8toStringERKNS0_13LocationRangeE:
 1874|   295k|    {
 1875|   295k|        return manifestJson(loc, false, U"");
 1876|   295k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11countLeavesEPNS1_10HeapObjectE:
  855|  3.54G|    {
  856|  3.54G|        if (auto *ext = dynamic_cast<HeapExtendedObject *>(obj)) {
  ------------------
  |  Branch (856:19): [True: 1.77G, False: 1.77G]
  ------------------
  857|  1.77G|            return countLeaves(ext->left) + countLeaves(ext->right);
  858|  1.77G|        } else {
  859|       |            // Must be a HeapLeafObject.
  860|  1.77G|            return 1;
  861|  1.77G|        }
  862|  3.54G|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11objectIndexERKNS0_13LocationRangeEPNS1_10HeapObjectEPKNS0_10IdentifierEj:
 1911|  11.1M|    {
 1912|  11.1M|        unsigned found_at = 0;
 1913|  11.1M|        HeapObject *self = obj;
 1914|  11.1M|        HeapLeafObject *found = findObject(f, obj, offset, found_at);
 1915|  11.1M|        if (found == nullptr) {
  ------------------
  |  Branch (1915:13): [True: 14, False: 11.1M]
  ------------------
 1916|     14|            throw makeError(loc, "field does not exist: " + encode_utf8(f->name));
 1917|     14|        }
 1918|  11.1M|        if (auto *simp = dynamic_cast<HeapSimpleObject *>(found)) {
  ------------------
  |  Branch (1918:19): [True: 11.1M, False: 0]
  ------------------
 1919|  11.1M|            auto it = simp->fields.find(f);
 1920|  11.1M|            const AST *body = it->second.body;
 1921|       |
 1922|  11.1M|            stack.newCall(loc, simp, self, found_at, simp->upValues);
 1923|  11.1M|            return body;
 1924|  11.1M|        } else {
 1925|       |            // If a HeapLeafObject is not HeapSimpleObject, it must be HeapComprehensionObject.
 1926|      0|            auto *comp = static_cast<HeapComprehensionObject *>(found);
 1927|      0|            auto it = comp->compValues.find(f);
 1928|      0|            auto *th = it->second;
 1929|      0|            BindingFrame binds = comp->upValues;
 1930|      0|            binds[comp->id] = th;
 1931|      0|            stack.newCall(loc, comp, self, found_at, binds);
 1932|      0|            return comp->value;
 1933|      0|        }
 1934|  11.1M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack26alreadyExecutingInvariantsEPNS1_10HeapObjectE:
  448|  9.14M|    {
  449|  2.50G|        for (int i = stack.size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (449:40): [True: 2.49G, False: 9.14M]
  ------------------
  450|  2.49G|            if (stack[i].kind == FRAME_INVARIANTS) {
  ------------------
  |  Branch (450:17): [True: 7.50M, False: 2.48G]
  ------------------
  451|  7.50M|                if (stack[i].self == self)
  ------------------
  |  Branch (451:21): [True: 992, False: 7.50M]
  ------------------
  452|    992|                    return true;
  453|  7.50M|            }
  454|  2.49G|        }
  455|  9.14M|        return false;
  456|  9.14M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack8newFrameIJNS1_9FrameKindENS0_13LocationRangeEEEEvDpT_:
  378|  9.14M|    {
  379|  9.14M|        stack.emplace_back(args...);
  380|  9.14M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter16objectInvariantsEPNS1_10HeapObjectES4_RjRNSt3__16vectorIPNS1_9HeapThunkENS6_9allocatorIS9_EEEE:
 1887|  41.2M|    {
 1888|  41.2M|        if (auto *ext = dynamic_cast<HeapExtendedObject *>(curr)) {
  ------------------
  |  Branch (1888:19): [True: 16.0M, False: 25.2M]
  ------------------
 1889|  16.0M|            objectInvariants(ext->right, self, counter, thunks);
 1890|  16.0M|            objectInvariants(ext->left, self, counter, thunks);
 1891|  25.2M|        } else {
 1892|  25.2M|            if (auto *simp = dynamic_cast<HeapSimpleObject *>(curr)) {
  ------------------
  |  Branch (1892:23): [True: 25.2M, False: 0]
  ------------------
 1893|  25.2M|                for (AST *assert : simp->asserts) {
  ------------------
  |  Branch (1893:34): [True: 65.8k, False: 25.2M]
  ------------------
 1894|  65.8k|                    auto *el_th = makeHeap<HeapThunk>(idInvariant, self, counter, assert);
 1895|  65.8k|                    el_th->upValues = simp->upValues;
 1896|  65.8k|                    thunks.push_back(el_th);
 1897|  65.8k|                }
 1898|  25.2M|            }
 1899|  25.2M|            counter++;
 1900|  25.2M|        }
 1901|  41.2M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRPNS0_3ASTEEEEPT_DpOT0_:
  567|  65.8k|    {
  568|  65.8k|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  569|  65.8k|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (569:13): [True: 327, False: 65.4k]
  ------------------
  570|       |            // Avoid the object we just made being collected.
  571|    327|            heap.markFrom(r);
  572|       |
  573|       |            // Mark from the stack.
  574|    327|            stack.mark(heap);
  575|       |
  576|       |            // Mark from the scratch register
  577|    327|            heap.markFrom(scratch);
  578|       |
  579|       |            // Mark from cached imports
  580|    327|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (580:35): [True: 0, False: 327]
  ------------------
  581|      0|                HeapThunk *thunk = pair.second->thunk;
  582|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (582:21): [True: 0, False: 0]
  ------------------
  583|      0|                    heap.markFrom(thunk);
  584|      0|            }
  585|       |
  586|  50.0k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (586:40): [True: 50.0k, False: 327]
  ------------------
  587|  50.0k|                heap.markFrom(sourceVal.second);
  588|  50.0k|            }
  589|       |
  590|       |            // Delete unreachable objects.
  591|    327|            heap.sweep();
  592|    327|        }
  593|  65.8k|        return r;
  594|  65.8k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter12manifestJsonERKNS0_13LocationRangeEbRKNSt3__112basic_stringIDiNS6_11char_traitsIDiEENS6_9allocatorIDiEEEE:
 3164|  2.58M|    {
 3165|       |        // Printing fields means evaluating and binding them, which can trigger
 3166|       |        // garbage collection.
 3167|       |
 3168|  2.58M|        UStringStream ss;
 3169|  2.58M|        switch (scratch.t) {
  ------------------
  |  Branch (3169:17): [True: 0, False: 2.58M]
  ------------------
 3170|   185k|            case Value::ARRAY: {
  ------------------
  |  Branch (3170:13): [True: 185k, False: 2.40M]
  ------------------
 3171|   185k|                HeapArray *arr = static_cast<HeapArray *>(scratch.v.h);
 3172|   185k|                if (arr->elements.size() == 0) {
  ------------------
  |  Branch (3172:21): [True: 50.9k, False: 134k]
  ------------------
 3173|  50.9k|                    ss << U"[ ]";
 3174|   134k|                } else {
 3175|   134k|                    const char32_t *prefix = multiline ? U"[\n" : U"[";
  ------------------
  |  Branch (3175:46): [True: 4.35k, False: 130k]
  ------------------
 3176|   134k|                    UString indent2 = multiline ? indent + U"   " : indent;
  ------------------
  |  Branch (3176:39): [True: 4.35k, False: 130k]
  ------------------
 3177|  1.10M|                    for (auto *thunk : arr->elements) {
  ------------------
  |  Branch (3177:38): [True: 1.10M, False: 134k]
  ------------------
 3178|  1.10M|                        LocationRange tloc = thunk->body == nullptr ? loc : thunk->body->location;
  ------------------
  |  Branch (3178:46): [True: 0, False: 1.10M]
  ------------------
 3179|  1.10M|                        if (thunk->filled) {
  ------------------
  |  Branch (3179:29): [True: 0, False: 1.10M]
  ------------------
 3180|      0|                            stack.newCall(loc, thunk, nullptr, 0, BindingFrame{});
 3181|       |                            // Keep arr alive when scratch is overwritten
 3182|      0|                            stack.top().val = scratch;
 3183|      0|                            scratch = thunk->content;
 3184|  1.10M|                        } else {
 3185|  1.10M|                            stack.newCall(loc, thunk, thunk->self, thunk->offset, thunk->upValues);
 3186|       |                            // Keep arr alive when scratch is overwritten
 3187|  1.10M|                            stack.top().val = scratch;
 3188|  1.10M|                            evaluate(thunk->body, stack.size());
 3189|  1.10M|                        }
 3190|  1.10M|                        auto element = manifestJson(tloc, multiline, indent2);
 3191|       |                        // Restore scratch
 3192|  1.10M|                        scratch = stack.top().val;
 3193|  1.10M|                        stack.pop();
 3194|  1.10M|                        ss << prefix << indent2 << element;
 3195|  1.10M|                        prefix = multiline ? U",\n" : U", ";
  ------------------
  |  Branch (3195:34): [True: 7.01k, False: 1.09M]
  ------------------
 3196|  1.10M|                    }
 3197|   134k|                    ss << (multiline ? U"\n" : U"") << indent << U"]";
  ------------------
  |  Branch (3197:28): [True: 3.92k, False: 130k]
  ------------------
 3198|   134k|                }
 3199|   185k|            } break;
 3200|       |
 3201|  54.7k|            case Value::BOOLEAN: ss << (scratch.v.b ? U"true" : U"false"); break;
  ------------------
  |  Branch (3201:13): [True: 54.7k, False: 2.53M]
  |  Branch (3201:41): [True: 19.1k, False: 35.5k]
  ------------------
 3202|       |
 3203|  1.64M|            case Value::NUMBER: ss << decode_utf8(jsonnet_unparse_number(scratch.v.d)); break;
  ------------------
  |  Branch (3203:13): [True: 1.64M, False: 940k]
  ------------------
 3204|       |
 3205|      5|            case Value::FUNCTION:
  ------------------
  |  Branch (3205:13): [True: 5, False: 2.58M]
  ------------------
 3206|      5|                throw makeError(loc, "couldn't manifest function in JSON output.");
 3207|       |
 3208|  1.64k|            case Value::NULL_TYPE: ss << U"null"; break;
  ------------------
  |  Branch (3208:13): [True: 1.64k, False: 2.58M]
  ------------------
 3209|       |
 3210|   634k|            case Value::OBJECT: {
  ------------------
  |  Branch (3210:13): [True: 634k, False: 1.95M]
  ------------------
 3211|   634k|                auto *obj = static_cast<HeapObject *>(scratch.v.h);
 3212|   634k|                runInvariants(loc, obj);
 3213|       |                // Using std::map has the useful side-effect of ordering the fields
 3214|       |                // alphabetically.
 3215|   634k|                std::map<UString, const Identifier *> fields;
 3216|   662k|                for (const auto &f : objectFields(obj, true)) {
  ------------------
  |  Branch (3216:36): [True: 662k, False: 634k]
  ------------------
 3217|   662k|                    fields[f->name] = f;
 3218|   662k|                }
 3219|   634k|                if (fields.size() == 0) {
  ------------------
  |  Branch (3219:21): [True: 291k, False: 342k]
  ------------------
 3220|   291k|                    ss << U"{ }";
 3221|   342k|                } else {
 3222|   342k|                    UString indent2 = multiline ? indent + U"   " : indent;
  ------------------
  |  Branch (3222:39): [True: 14.6k, False: 327k]
  ------------------
 3223|   342k|                    const char32_t *prefix = multiline ? U"{\n" : U"{";
  ------------------
  |  Branch (3223:46): [True: 14.6k, False: 327k]
  ------------------
 3224|   580k|                    for (const auto &f : fields) {
  ------------------
  |  Branch (3224:40): [True: 580k, False: 342k]
  ------------------
 3225|       |                        // pushes FRAME_CALL
 3226|   580k|                        const AST *body = objectIndex(loc, obj, f.second, 0);
 3227|   580k|                        stack.top().val = scratch;
 3228|   580k|                        evaluate(body, stack.size());
 3229|   580k|                        auto vstr = manifestJson(body->location, multiline, indent2);
 3230|       |                        // Reset scratch so that the object we're manifesting doesn't
 3231|       |                        // get GC'd.
 3232|   580k|                        scratch = stack.top().val;
 3233|   580k|                        stack.pop();
 3234|   580k|                        ss << prefix << indent2 << jsonnet_string_unparse(f.first, false) << U": "
 3235|   580k|                           << vstr;
 3236|   580k|                        prefix = multiline ? U",\n" : U", ";
  ------------------
  |  Branch (3236:34): [True: 31.8k, False: 548k]
  ------------------
 3237|   580k|                    }
 3238|   342k|                    ss << (multiline ? U"\n" : U"") << indent << U"}";
  ------------------
  |  Branch (3238:28): [True: 256, False: 342k]
  ------------------
 3239|   342k|                }
 3240|   634k|            } break;
 3241|       |
 3242|  64.4k|            case Value::STRING: {
  ------------------
  |  Branch (3242:13): [True: 64.4k, False: 2.52M]
  ------------------
 3243|  64.4k|                const UString &str = static_cast<HeapString *>(scratch.v.h)->value;
 3244|  64.4k|                ss << jsonnet_string_unparse(str, false);
 3245|  64.4k|            } break;
 3246|  2.58M|        }
 3247|  2.39M|        return ss.str();
 3248|  2.58M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13runInvariantsERKNS0_13LocationRangeEPNS1_10HeapObjectE:
 1937|   634k|    {
 1938|   634k|        if (stack.alreadyExecutingInvariants(self))
  ------------------
  |  Branch (1938:13): [True: 992, False: 633k]
  ------------------
 1939|    992|            return;
 1940|       |
 1941|   633k|        unsigned counter = 0;
 1942|   633k|        unsigned initial_stack_size = stack.size();
 1943|   633k|        stack.newFrame(FRAME_INVARIANTS, loc);
 1944|   633k|        std::vector<HeapThunk *> &thunks = stack.top().thunks;
 1945|   633k|        objectInvariants(self, self, counter, thunks);
 1946|   633k|        if (thunks.size() == 0) {
  ------------------
  |  Branch (1946:13): [True: 615k, False: 17.6k]
  ------------------
 1947|   615k|            stack.pop();
 1948|   615k|            return;
 1949|   615k|        }
 1950|  17.6k|        HeapThunk *thunk = thunks[0];
 1951|  17.6k|        stack.top().elementId = 1;
 1952|  17.6k|        stack.top().self = self;
 1953|  17.6k|        stack.newCall(loc, thunk, thunk->self, thunk->offset, thunk->upValues);
 1954|  17.6k|        evaluate(thunk->body, initial_stack_size);
 1955|  17.6k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111InterpreterD2Ev:
  957|  4.16k|    {
  958|  4.16k|        for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (958:31): [True: 105, False: 4.16k]
  ------------------
  959|    105|            delete pair.second;
  960|    105|        }
  961|  4.16k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter14manifestStreamEb:
 3294|  2.32k|    {
 3295|  2.32k|        std::vector<std::string> r;
 3296|  2.32k|        LocationRange loc("During manifestation");
 3297|  2.32k|        if (scratch.t != Value::ARRAY) {
  ------------------
  |  Branch (3297:13): [True: 1.47k, False: 842]
  ------------------
 3298|  1.47k|            std::stringstream ss;
 3299|  1.47k|            ss << "stream mode: top-level object was a " << type_str(scratch.t) << ", "
 3300|  1.47k|               << "should be an array whose elements hold "
 3301|  1.47k|               << "the JSON for each document in the stream.";
 3302|  1.47k|            throw makeError(loc, ss.str());
 3303|  1.47k|        }
 3304|    842|        auto *arr = static_cast<HeapArray *>(scratch.v.h);
 3305|   620k|        for (auto *thunk : arr->elements) {
  ------------------
  |  Branch (3305:26): [True: 620k, False: 842]
  ------------------
 3306|   620k|            LocationRange tloc = thunk->body == nullptr ? loc : thunk->body->location;
  ------------------
  |  Branch (3306:34): [True: 0, False: 620k]
  ------------------
 3307|   620k|            if (thunk->filled) {
  ------------------
  |  Branch (3307:17): [True: 0, False: 620k]
  ------------------
 3308|      0|                stack.newCall(loc, thunk, nullptr, 0, BindingFrame{});
 3309|       |                // Keep arr alive when scratch is overwritten
 3310|      0|                stack.top().val = scratch;
 3311|      0|                scratch = thunk->content;
 3312|   620k|            } else {
 3313|   620k|                stack.newCall(loc, thunk, thunk->self, thunk->offset, thunk->upValues);
 3314|       |                // Keep arr alive when scratch is overwritten
 3315|   620k|                stack.top().val = scratch;
 3316|   620k|                evaluate(thunk->body, stack.size());
 3317|   620k|            }
 3318|   620k|            UString element = string ? manifestString(tloc) : manifestJson(tloc, true, U"");
  ------------------
  |  Branch (3318:31): [True: 0, False: 620k]
  ------------------
 3319|   620k|            scratch = stack.top().val;
 3320|   620k|            stack.pop();
 3321|   620k|            r.push_back(encode_utf8(element));
 3322|   620k|        }
 3323|    842|        return r;
 3324|  2.32k|    }

_ZN7jsonnet8internal10TraceFrameC2ERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
   33|   267k|    {
   34|   267k|    }
_ZN7jsonnet8internal12RuntimeErrorC2ENSt3__16vectorINS0_10TraceFrameENS2_9allocatorIS4_EEEERKNS2_12basic_stringIcNS2_11char_traitsIcEENS5_IcEEEE:
   45|  3.45k|    {
   46|  3.45k|    }

_ZN2c43yml9CallbacksC2Ev:
   67|      2|{
   68|      2|}
_ZN2c43yml13get_callbacksEv:
  119|      2|{
  120|      2|    return s_default_callbacks;
  121|      2|}

