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 "gc/Marking.h" michael@0: #include "jit/JitCompartment.h" michael@0: #if defined(JS_CODEGEN_X86) michael@0: # include "jit/x86/MacroAssembler-x86.h" michael@0: #elif defined(JS_CODEGEN_X64) michael@0: # include "jit/x64/MacroAssembler-x64.h" michael@0: #else michael@0: # error "Wrong architecture. Only x86 and x64 should build this file!" michael@0: #endif michael@0: michael@0: using namespace js; michael@0: using namespace js::jit; michael@0: michael@0: void michael@0: AssemblerX86Shared::copyJumpRelocationTable(uint8_t *dest) michael@0: { michael@0: if (jumpRelocations_.length()) michael@0: memcpy(dest, jumpRelocations_.buffer(), jumpRelocations_.length()); michael@0: } michael@0: michael@0: void michael@0: AssemblerX86Shared::copyDataRelocationTable(uint8_t *dest) michael@0: { michael@0: if (dataRelocations_.length()) michael@0: memcpy(dest, dataRelocations_.buffer(), dataRelocations_.length()); michael@0: } michael@0: michael@0: void michael@0: AssemblerX86Shared::copyPreBarrierTable(uint8_t *dest) michael@0: { michael@0: if (preBarriers_.length()) michael@0: memcpy(dest, preBarriers_.buffer(), preBarriers_.length()); michael@0: } michael@0: michael@0: static void michael@0: TraceDataRelocations(JSTracer *trc, uint8_t *buffer, CompactBufferReader &reader) michael@0: { michael@0: while (reader.more()) { michael@0: size_t offset = reader.readUnsigned(); michael@0: void **ptr = JSC::X86Assembler::getPointerRef(buffer + offset); michael@0: michael@0: #ifdef JS_PUNBOX64 michael@0: // All pointers on x64 will have the top bits cleared. If those bits michael@0: // are not cleared, this must be a Value. michael@0: uintptr_t *word = reinterpret_cast(ptr); michael@0: if (*word >> JSVAL_TAG_SHIFT) { michael@0: jsval_layout layout; michael@0: layout.asBits = *word; michael@0: Value v = IMPL_TO_JSVAL(layout); michael@0: gc::MarkValueUnbarriered(trc, &v, "ion-masm-value"); michael@0: JS_ASSERT(*word == JSVAL_TO_IMPL(v).asBits); michael@0: continue; michael@0: } michael@0: #endif michael@0: michael@0: // No barrier needed since these are constants. michael@0: gc::MarkGCThingUnbarriered(trc, reinterpret_cast(ptr), "ion-masm-ptr"); michael@0: } michael@0: } michael@0: michael@0: michael@0: void michael@0: AssemblerX86Shared::TraceDataRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader) michael@0: { michael@0: ::TraceDataRelocations(trc, code->raw(), reader); michael@0: } michael@0: michael@0: void michael@0: AssemblerX86Shared::trace(JSTracer *trc) michael@0: { michael@0: for (size_t i = 0; i < jumps_.length(); i++) { michael@0: RelativePatch &rp = jumps_[i]; michael@0: if (rp.kind == Relocation::JITCODE) { michael@0: JitCode *code = JitCode::FromExecutable((uint8_t *)rp.target); michael@0: MarkJitCodeUnbarriered(trc, &code, "masmrel32"); michael@0: JS_ASSERT(code == JitCode::FromExecutable((uint8_t *)rp.target)); michael@0: } michael@0: } michael@0: if (dataRelocations_.length()) { michael@0: CompactBufferReader reader(dataRelocations_); michael@0: ::TraceDataRelocations(trc, masm.buffer(), reader); michael@0: } michael@0: } michael@0: michael@0: void michael@0: AssemblerX86Shared::executableCopy(void *buffer) michael@0: { michael@0: masm.executableCopy(buffer); michael@0: } michael@0: michael@0: void michael@0: AssemblerX86Shared::processCodeLabels(uint8_t *rawCode) michael@0: { michael@0: for (size_t i = 0; i < codeLabels_.length(); i++) { michael@0: CodeLabel label = codeLabels_[i]; michael@0: Bind(rawCode, label.dest(), rawCode + label.src()->offset()); michael@0: } michael@0: } michael@0: michael@0: AssemblerX86Shared::Condition michael@0: AssemblerX86Shared::InvertCondition(Condition cond) michael@0: { michael@0: switch (cond) { michael@0: case Zero: michael@0: return NonZero; michael@0: case NonZero: michael@0: return Zero; michael@0: case LessThan: michael@0: return GreaterThanOrEqual; michael@0: case LessThanOrEqual: michael@0: return GreaterThan; michael@0: case GreaterThan: michael@0: return LessThanOrEqual; michael@0: case GreaterThanOrEqual: michael@0: return LessThan; michael@0: case Above: michael@0: return BelowOrEqual; michael@0: case AboveOrEqual: michael@0: return Below; michael@0: case Below: michael@0: return AboveOrEqual; michael@0: case BelowOrEqual: michael@0: return Above; michael@0: default: michael@0: MOZ_ASSUME_UNREACHABLE("unexpected condition"); michael@0: } michael@0: }