/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is [Open Source Virtual Machine]. * * The Initial Developer of the Original Code is * Adobe System Incorporated. * Portions created by the Initial Developer are Copyright (C) 2004-2007 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Adobe AS3 Team * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef __nanojit_h__ #define __nanojit_h__ #include #include "avmplus.h" #ifdef FEATURE_NANOJIT #ifdef AVMPLUS_IA32 #define NANOJIT_IA32 #elif AVMPLUS_ARM #define NANOJIT_ARM #elif AVMPLUS_PPC #define NANOJIT_PPC #elif AVMPLUS_SPARC #define NANOJIT_SPARC #elif AVMPLUS_AMD64 #define NANOJIT_AMD64 #define NANOJIT_64BIT #else #error "unknown nanojit architecture" #endif /* If we're using MMGC, using operator delete on a GCFinalizedObject is problematic: in particular, calling it from inside a dtor is risky because the dtor for the sub-object might already have been called, wrecking its vtable and ending up in the wrong version of operator delete (the global version rather than the class-specific one). Calling GC::Free directly is fine (since it ignores the vtable), so we macro-ize to make the distinction. macro-ization of operator new isn't strictly necessary, but is done to bottleneck both sides of the new/delete pair to forestall future needs. */ #ifdef MMGC_API // separate overloads because GCObject and GCFinalizedObjects have different dtors // (GCFinalizedObject's is virtual, GCObject's is not) inline void mmgc_delete(GCObject* o) { GC* g = GC::GetGC(o); if (g->Collecting()) g->Free(o); else delete o; } inline void mmgc_delete(GCFinalizedObject* o) { GC* g = GC::GetGC(o); if (g->Collecting()) g->Free(o); else delete o; } #define NJ_NEW(gc, cls) new (gc) cls #define NJ_DELETE(obj) do { mmgc_delete(obj); } while (0) #else #define NJ_NEW(gc, cls) new (gc) cls #define NJ_DELETE(obj) do { delete obj; } while (0) #endif // Embed no-op macros that let Valgrind work with the JIT. #ifdef MOZ_VALGRIND # define JS_VALGRIND #endif #ifdef JS_VALGRIND # include #else # define VALGRIND_DISCARD_TRANSLATIONS(addr, szB) #endif namespace nanojit { /** * ------------------------------------------- * START AVM bridging definitions * ------------------------------------------- */ class Fragment; class LIns; struct SideExit; class RegAlloc; typedef avmplus::AvmCore AvmCore; typedef avmplus::OSDep OSDep; typedef avmplus::GCSortedMap FragmentMap; typedef avmplus::SortedMap RegAllocMap; typedef avmplus::List InsList; typedef avmplus::List StringList; const uint32_t MAXARGS = 8; #ifdef MOZ_NO_VARADIC_MACROS static void NanoAssertMsgf(bool a,const char *f,...) {} static void NanoAssertMsg(bool a,const char *m) {} static void NanoAssert(bool a) {} #elif defined(_DEBUG) #define __NanoAssertMsgf(a, file_, line_, f, ...) \ if (!(a)) { \ fprintf(stderr, "Assertion failed: " f "%s (%s:%d)\n", __VA_ARGS__, #a, file_, line_); \ NanoAssertFail(); \ } #define _NanoAssertMsgf(a, file_, line_, f, ...) __NanoAssertMsgf(a, file_, line_, f, __VA_ARGS__) #define NanoAssertMsgf(a,f,...) do { __NanoAssertMsgf(a, __FILE__, __LINE__, f ": ", __VA_ARGS__); } while (0) #define NanoAssertMsg(a,m) do { __NanoAssertMsgf(a, __FILE__, __LINE__, "\"%s\": ", m); } while (0) #define NanoAssert(a) do { __NanoAssertMsgf(a, __FILE__, __LINE__, "%s", ""); } while (0) #else #define NanoAssertMsgf(a,f,...) do { } while (0) /* no semi */ #define NanoAssertMsg(a,m) do { } while (0) /* no semi */ #define NanoAssert(a) do { } while (0) /* no semi */ #endif /* * Sun Studio C++ compiler has a bug * "sizeof expression not accepted as size of array parameter" * The bug number is 6688515. It is not public yet. * Turn off this assert for Sun Studio until this bug is fixed. */ #ifdef __SUNPRO_CC #define NanoStaticAssert(condition) #else #define NanoStaticAssert(condition) \ extern void nano_static_assert(int arg[(condition) ? 1 : -1]) #endif /** * ------------------------------------------- * END AVM bridging definitions * ------------------------------------------- */ } #ifdef AVMPLUS_VERBOSE #define NJ_VERBOSE 1 #define NJ_PROFILE 1 #endif #ifdef MOZ_NO_VARADIC_MACROS #include #define verbose_outputf if (_logc->lcbits & LC_Assembly) \ Assembler::outputf #define verbose_only(x) x #elif defined(NJ_VERBOSE) #include #define verbose_outputf if (_logc->lcbits & LC_Assembly) \ Assembler::outputf #define verbose_only(...) __VA_ARGS__ #else #define verbose_outputf #define verbose_only(...) #endif /*NJ_VERBOSE*/ #ifdef _DEBUG #define debug_only(x) x #else #define debug_only(x) #endif /* DEBUG */ #ifdef NJ_PROFILE #define counter_struct_begin() struct { #define counter_struct_end() } _stats; #define counter_define(x) int32_t x #define counter_value(x) _stats.x #define counter_set(x,v) (counter_value(x)=(v)) #define counter_adjust(x,i) (counter_value(x)+=(int32_t)(i)) #define counter_reset(x) counter_set(x,0) #define counter_increment(x) counter_adjust(x,1) #define counter_decrement(x) counter_adjust(x,-1) #define profile_only(x) x #else #define counter_struct_begin() #define counter_struct_end() #define counter_define(x) #define counter_value(x) #define counter_set(x,v) #define counter_adjust(x,i) #define counter_reset(x) #define counter_increment(x) #define counter_decrement(x) #define profile_only(x) #endif /* NJ_PROFILE */ #define isS8(i) ( int32_t(i) == int8_t(i) ) #define isU8(i) ( int32_t(i) == uint8_t(i) ) #define isS16(i) ( int32_t(i) == int16_t(i) ) #define isU16(i) ( int32_t(i) == uint16_t(i) ) #define isS24(i) ( ((int32_t(i)<<8)>>8) == (i) ) #define alignTo(x,s) ((((uintptr_t)(x)))&~(((uintptr_t)s)-1)) #define alignUp(x,s) ((((uintptr_t)(x))+(((uintptr_t)s)-1))&~(((uintptr_t)s)-1)) #define pageTop(x) ( alignTo(x,NJ_PAGE_SIZE) ) #define pageDataStart(x) ( alignTo(x,NJ_PAGE_SIZE) + sizeof(PageHeader) ) #define pageBottom(x) ( alignTo(x,NJ_PAGE_SIZE) + NJ_PAGE_SIZE - 1 ) #define samepage(x,y) ( pageTop(x) == pageTop(y) ) // ------------------------------------------------------------------- // START debug-logging definitions // ------------------------------------------------------------------- /* Debug printing stuff. All Nanojit and jstracer debug printing should be routed through LogControl::printf. Don't use ad-hoc calls to printf, fprintf(stderr, ...) etc. Similarly, don't use ad-hoc getenvs etc to decide whether or not to print debug output. Instead consult the relevant control bit in LogControl::lcbits in the LogControl object you are supplied with. */ # if defined(__GNUC__) # define PRINTF_CHECK(x, y) __attribute__((format(__printf__, x, y))) # else # define PRINTF_CHECK(x, y) # endif namespace nanojit { // LogControl, a class for controlling and routing debug output enum LC_Bits { /* Output control bits for Nanojit code. Only use bits 15 and below, so that callers can use bits 16 and above for themselves. */ // TODO: add entries for the writer pipeline LC_Liveness = 1<<6, // (show LIR liveness analysis) LC_ReadLIR = 1<<5, // As read from LirBuffer LC_AfterSF_SP = 1<<4, // After StackFilter(sp) LC_AfterSF_RP = 1<<3, // After StackFilter(rp) LC_RegAlloc = 1<<2, // stuff to do with reg alloc LC_Assembly = 1<<1, // final assembly LC_NoCodeAddrs = 1<<0 // (don't show code addresses on asm output) }; class LogControl { public: // All Nanojit and jstracer printing should be routed through // this function. void printf( const char* format, ... ) PRINTF_CHECK(2,3); // An OR of LC_Bits values, indicating what should be output uint32_t lcbits; }; } // ------------------------------------------------------------------- // END debug-logging definitions // ------------------------------------------------------------------- #include "Allocator.h" #include "Native.h" #include "CodeAlloc.h" #include "LIR.h" #include "RegAlloc.h" #include "Fragmento.h" #include "Assembler.h" #endif // FEATURE_NANOJIT #endif // __nanojit_h__