Assembler-x86.cpp (2629B)
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 #include "jit/x86/Assembler-x86.h" 8 9 #include "gc/Marking.h" 10 #include "util/Memory.h" 11 #include "wasm/WasmFrame.h" 12 13 using namespace js; 14 using namespace js::jit; 15 16 ABIArg ABIArgGenerator::next(MIRType type) { 17 switch (type) { 18 case MIRType::Int32: 19 case MIRType::Float32: 20 case MIRType::Pointer: 21 case MIRType::WasmAnyRef: 22 case MIRType::WasmArrayData: 23 case MIRType::StackResults: 24 current_ = ABIArg(stackOffset_); 25 stackOffset_ += sizeof(uint32_t); 26 break; 27 case MIRType::Double: 28 case MIRType::Int64: 29 current_ = ABIArg(stackOffset_); 30 stackOffset_ += sizeof(uint64_t); 31 break; 32 case MIRType::Simd128: 33 MOZ_ASSERT(kind_ == ABIKind::Wasm); 34 // On Win64, >64 bit args need to be passed by reference. However, wasm 35 // doesn't allow passing SIMD values to JS, so the only way to reach this 36 // is wasm to wasm calls. Ergo we can break the native ABI here and use 37 // the Wasm ABI instead. 38 stackOffset_ = AlignBytes(stackOffset_, SimdMemoryAlignment); 39 current_ = ABIArg(stackOffset_); 40 stackOffset_ += Simd128DataSize; 41 break; 42 default: 43 MOZ_CRASH("Unexpected argument type"); 44 } 45 return current_; 46 } 47 48 void Assembler::executableCopy(uint8_t* buffer) { 49 AssemblerX86Shared::executableCopy(buffer); 50 for (RelativePatch& rp : jumps_) { 51 X86Encoding::SetRel32(buffer + rp.offset, rp.target); 52 } 53 } 54 55 class RelocationIterator { 56 CompactBufferReader reader_; 57 uint32_t offset_; 58 59 public: 60 explicit RelocationIterator(CompactBufferReader& reader) : reader_(reader) {} 61 62 bool read() { 63 if (!reader_.more()) { 64 return false; 65 } 66 offset_ = reader_.readUnsigned(); 67 return true; 68 } 69 70 uint32_t offset() const { return offset_; } 71 }; 72 73 static inline JitCode* CodeFromJump(uint8_t* jump) { 74 uint8_t* target = (uint8_t*)X86Encoding::GetRel32Target(jump); 75 return JitCode::FromExecutable(target); 76 } 77 78 void Assembler::TraceJumpRelocations(JSTracer* trc, JitCode* code, 79 CompactBufferReader& reader) { 80 RelocationIterator iter(reader); 81 while (iter.read()) { 82 JitCode* child = CodeFromJump(code->raw() + iter.offset()); 83 TraceManuallyBarrieredEdge(trc, &child, "rel32"); 84 MOZ_ASSERT(child == CodeFromJump(code->raw() + iter.offset())); 85 } 86 }