CacheIRAOT.cpp (5845B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifdef ENABLE_JS_AOT_ICS 8 9 # include "jit/CacheIRAOT.h" 10 11 # include "jsmath.h" 12 # include "jstypes.h" 13 14 # include "gc/AllocKind.h" 15 # include "jit/CacheIR.h" 16 # include "jit/CacheIRAOTGenerated.h" 17 # include "jit/JitZone.h" 18 # include "js/ScalarType.h" 19 # include "js/Value.h" 20 # include "vm/CompletionKind.h" 21 # include "vm/Opcodes.h" 22 # include "wasm/WasmValType.h" 23 24 // Include null pointers for "native" pointers: an AOT-loaded stub 25 // should not bake in an arbitrary pointer observed from a previous 26 // execution. In any case, the AOT corpus should not include any ICs 27 // that bake in pointers (baseline does not generate any). 28 29 # if JS_BITS_PER_WORD == 32 30 # define NATIVE_NULLPTR 0, 0, 0, 0 31 # elif JS_BITS_PER_WORD == 64 32 # define NATIVE_NULLPTR 0, 0, 0, 0, 0, 0, 0, 0 33 # else 34 # error Please add a case for a non-32/64-bit system here. 35 # endif 36 37 // These correspond to the CacheIRWriter definitions of the serialized 38 // CacheIR format. 39 40 # define OP(op) \ 41 uint8_t(uint16_t(CacheOp::op) & 0xff), uint8_t(uint16_t(CacheOp::op) >> 8), 42 # define ID(id) id, 43 # define OFFSET(off) off, 44 # define BOOL(x) x, 45 # define BYTE(x) x, 46 # define JSOP(op) uint8_t(JSOp::op), 47 # define TYPEOFEQOPERAND(value) value, 48 # define STATICSTRING(p) NATIVE_NULLPTR, 49 # define INT32(i) \ 50 uint32_t(i) & 0xff, (uint32_t(i) >> 8) & 0xff, (uint32_t(i) >> 16) & 0xff, \ 51 (uint32_t(i) >> 24) & 0xff, 52 # define UINT32(i) \ 53 (i) & 0xff, ((i) >> 8) & 0xff, ((i) >> 16) & 0xff, ((i) >> 24) & 0xff, 54 # define CALLFLAGS(f) f, 55 # define WHYMAGIC(m) m, 56 # define SCALARTYPE(name) uint8_t(Scalar::Type::name), 57 # define UNARYMATHFUNC(name) uint8_t(UnaryMathFunction::name), 58 # define VALUETYPE(name) uint8_t(name), 59 # define NATIVEIMM(p) NATIVE_NULLPTR, 60 # define GUARDCLASSKIND(name) uint8_t(GuardClassKind::name), 61 # define ARRAYBUFFERVIEWKIND(name) uint8_t(ArrayBufferViewKind::name), 62 # define WASMVALTYPE(name) uint8_t(wasm::ValType::Kind::name), 63 # define ALLOCKIND(name) uint8_t(gc::AllocKind::name), 64 # define COMPLETIONKIND(name) uint8_t(CompletionKind::name), 65 # define REALMFUSE(i) i, 66 67 // Other macros used to serialize parts of the CacheIRWriter. 68 # define STUBFIELD(ty) AOTStubFieldData{StubField::Type::ty, 0}, 69 # define LASTUSED(n) n, 70 71 // First, generate individual IC bodies. 72 73 # define IC_BODY(idx, _kind, _num_input_operands, _num_operand_ids, \ 74 _num_instructions, _typedata, _stubdatasize, _stubfields, \ 75 _lastused, ops) \ 76 static const uint8_t IC##idx[] = {ops}; 77 78 JS_AOT_IC_DATA(IC_BODY) 79 80 // Generate the stubfield lists. 81 82 # define IC_STUBFIELD(idx, _kind, _num_input_operands, _num_operand_ids, \ 83 _num_instructions, _typedata, _stubdatasize, \ 84 stubfields, _lastused, _ops) \ 85 static const AOTStubFieldData IC##idx##StubFields[] = {stubfields}; 86 87 JS_AOT_IC_DATA(IC_STUBFIELD) 88 89 // Generate the operand-last-used lists. 90 91 # define IC_LASTUSED(idx, _kind, _num_input_operands, _num_operand_ids, \ 92 _num_instructions, _typedata, _stubdatasize, \ 93 _stubfields, lastused, _ops) \ 94 static const uint32_t IC##idx##LastUsed[] = {lastused}; 95 96 JS_AOT_IC_DATA(IC_LASTUSED) 97 98 // Now, generate the toplevel list of AOT structs from which we can 99 // reconstitute a CacheIRWriter. 100 101 # define IC_TOP(idx, kind, num_input_operands, num_operand_ids, \ 102 num_instructions, typedata, stubdatasize, _stubfields, \ 103 _lastused, _ops) \ 104 CacheIRAOTStub{ \ 105 CacheKind::kind, \ 106 num_operand_ids, \ 107 num_input_operands, \ 108 num_instructions, \ 109 TypeData(typedata), \ 110 stubdatasize, \ 111 IC##idx##StubFields, \ 112 sizeof(IC##idx##StubFields) / sizeof(IC##idx##StubFields[0]), \ 113 IC##idx##LastUsed, \ 114 IC##idx, \ 115 sizeof(IC##idx)}, 116 117 static const CacheIRAOTStub stubs[] = {JS_AOT_IC_DATA(IC_TOP)}; 118 119 mozilla::Span<const CacheIRAOTStub> js::jit::GetAOTStubs() { 120 return mozilla::Span(stubs, sizeof(stubs) / sizeof(stubs[0])); 121 } 122 123 CacheIRWriter::CacheIRWriter(JSContext* cx, const CacheIRAOTStub& stub) 124 : CustomAutoRooter(cx), 125 # ifdef DEBUG 126 cx_(cx), 127 # endif 128 tooLarge_(false), 129 lastOffset_(0), 130 lastIndex_(0) { 131 nextOperandId_ = stub.numOperandIds; 132 nextInstructionId_ = stub.numInstructions; 133 numInputOperands_ = stub.numInputOperands; 134 typeData_ = stub.typeData; 135 stubDataSize_ = stub.stubDataSize; 136 for (size_t i = 0; i < stub.stubfieldCount; i++) { 137 buffer_.propagateOOM(stubFields_.append( 138 StubField(stub.stubfields[i].data, stub.stubfields[i].type))); 139 } 140 for (uint32_t i = 0; i < stub.numOperandIds; i++) { 141 buffer_.propagateOOM(operandLastUsed_.append(stub.operandLastUsed[i])); 142 } 143 buffer_.writeBytes(stub.data, stub.dataLength); 144 } 145 146 #endif /* ENABLE_JS_AOT_ICS */