michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "jit/x86/Assembler-x86.h" michael@0: michael@0: #include "gc/Marking.h" michael@0: michael@0: using namespace js; michael@0: using namespace js::jit; michael@0: michael@0: ABIArgGenerator::ABIArgGenerator() michael@0: : stackOffset_(0), michael@0: current_() michael@0: {} michael@0: michael@0: ABIArg michael@0: ABIArgGenerator::next(MIRType type) michael@0: { michael@0: current_ = ABIArg(stackOffset_); michael@0: switch (type) { michael@0: case MIRType_Int32: michael@0: case MIRType_Pointer: michael@0: stackOffset_ += sizeof(uint32_t); michael@0: break; michael@0: case MIRType_Float32: // Float32 moves are actually double moves michael@0: case MIRType_Double: michael@0: stackOffset_ += sizeof(uint64_t); michael@0: break; michael@0: default: michael@0: MOZ_ASSUME_UNREACHABLE("Unexpected argument type"); michael@0: } michael@0: return current_; michael@0: } michael@0: michael@0: const Register ABIArgGenerator::NonArgReturnVolatileReg0 = ecx; michael@0: const Register ABIArgGenerator::NonArgReturnVolatileReg1 = edx; michael@0: const Register ABIArgGenerator::NonVolatileReg = ebx; michael@0: michael@0: void michael@0: Assembler::executableCopy(uint8_t *buffer) michael@0: { michael@0: AssemblerX86Shared::executableCopy(buffer); michael@0: michael@0: for (size_t i = 0; i < jumps_.length(); i++) { michael@0: RelativePatch &rp = jumps_[i]; michael@0: JSC::X86Assembler::setRel32(buffer + rp.offset, rp.target); michael@0: } michael@0: } michael@0: michael@0: class RelocationIterator michael@0: { michael@0: CompactBufferReader reader_; michael@0: uint32_t offset_; michael@0: michael@0: public: michael@0: RelocationIterator(CompactBufferReader &reader) michael@0: : reader_(reader) michael@0: { } michael@0: michael@0: bool read() { michael@0: if (!reader_.more()) michael@0: return false; michael@0: offset_ = reader_.readUnsigned(); michael@0: return true; michael@0: } michael@0: michael@0: uint32_t offset() const { michael@0: return offset_; michael@0: } michael@0: }; michael@0: michael@0: static inline JitCode * michael@0: CodeFromJump(uint8_t *jump) michael@0: { michael@0: uint8_t *target = (uint8_t *)JSC::X86Assembler::getRel32Target(jump); michael@0: return JitCode::FromExecutable(target); michael@0: } michael@0: michael@0: void michael@0: Assembler::TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader) michael@0: { michael@0: RelocationIterator iter(reader); michael@0: while (iter.read()) { michael@0: JitCode *child = CodeFromJump(code->raw() + iter.offset()); michael@0: MarkJitCodeUnbarriered(trc, &child, "rel32"); michael@0: JS_ASSERT(child == CodeFromJump(code->raw() + iter.offset())); michael@0: } michael@0: } michael@0: