/* [<][>][^][v][top][bottom][index][help] */
/* ***** 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) 1993-2006
* 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 __avmplus_VMPI__
#define __avmplus_VMPI__
// Belt and suspenders...
#ifdef DEBUG
#ifndef _DEBUG
#define _DEBUG
#endif
#endif
#ifdef _DEBUG
#ifndef DEBUG
#define DEBUG
#endif
#endif
// Include feature settings. These also perform platform sniffing if platform
// settings are not provided eg on the command line.
#ifdef AVMSHELL_BUILD
#include "avmshell-features.h"
#else
/* The embedding host must provide this file in some directory that's included in
* header search paths. It must define a value (0 or 1) for every feature
* required by avmplus, see shell/avmshell-features.h for a model, also see
* core/avmfeatures.as for documentation of the feature system.
*/
#include "avmhost-features.h"
#endif
// Include the feature system here so that the platform files can depend on
// the internal (VMCFG_, etc) names rather than feature names. Eases
// maintainability.
#include "avmfeatures.h"
// used by platform headers below
typedef void * vmpi_thread_t;
#if AVMSYSTEM_WIN32
#include "win32/win32-platform.h"
#elif AVMSYSTEM_UNIX
#include "unix/unix-platform.h"
#elif AVMSYSTEM_MAC
#include "mac/mac-platform.h"
#elif AVMSYSTEM_SYMBIAN
#include "symbian/symbian-platform.h"
#endif
// Catchall, though in general the platform files are really responsible for giving
// REALLY_INLINE and FASTCALL a definition.
#ifndef REALLY_INLINE
#define REALLY_INLINE inline
#endif
#ifndef FASTCALL
#define FASTCALL
#endif
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
// Legacy types used by some embedding host code, eg avmplus::uint64.
// These types are not to be used inside the avm code.
namespace avmplus
{
typedef int64_t int64;
typedef int64_t sint64;
typedef uint64_t uint64;
typedef uint32_t uint32;
typedef int32_t int32;
typedef int32_t sint32;
typedef uint16_t uint16;
typedef int16_t int16;
typedef int16_t sint16;
typedef uint8_t uint8;
typedef int8_t int8;
typedef int8_t sint8;
typedef uintptr_t uintptr;
typedef intptr_t sintptr;
typedef uint8_t byte;
}
/* wchar is our version of wchar_t, since wchar_t is different sizes
on different platforms, but we want to use UTF-16 uniformly. */
typedef uint16_t wchar;
/**
* This method should return the difference in milliseconds between local time and UTC
* @return offset in milliseconds
*/
extern double VMPI_getLocalTimeOffset();
/**
* This method should return the Daylight Savings time adjustment in milliseconds
* @return number of milliseconds corresponding to daylight savings adjustment when active, 0 otherwise
*/
extern double VMPI_getDaylightSavingsTA(double time);
/**
* This method should return the current UTC date and time in milliseconds
* @return UTC date and time in milliseconds
*/
extern double VMPI_getDate();
/**
* This method should return the system time in milliseconds
* The implementation of this method could either return the time elapsed since the system started or since epoc
* @return number of milliseconds elapsed
*/
extern uint64_t VMPI_getTime();
/**
* This method is called to output log messages
* The implementation of this method is platform-defined
* @param message NULL-terminated UTF8-encoded string
* @return none
*/
extern void VMPI_log(const char* message);
/**
* This method is called to output debugging messages
* This method is specifically for debugging purposes and is invoked to output useful debug informaton
* The implementation of this method is platform-defined. For example, it could be used to output the message to an IDE
* @param message NULL-terminated UTF8-encoded string
* @return none
*/
extern void VMPI_debugLog(const char* message);
/**
* This method is called to interrupt the program execution during debugging
* Upon a call to this method, the platform execution should interrupt the program execution
* while maintaining the current call stack and associated program information such as the registers
* and return the control back to the user/developer
* This method is specifically for debugging purposes and is invoked to enter a debug interrupt to examine information like the variable values or call stack
* The implementation of this method is platform-defined.
* On platforms that cannot support debug interrupts the program execution should be aborted
* @return none
*/
extern void VMPI_debugBreak();
/**
* This method is used to request a block of memory from the system
* @param size size, in bytes, of memory block requested
* @return pointer to the start of memory block if allocation was successful, NULL otherwise
*/
extern void* VMPI_alloc(size_t size);
/**
* This method is used to free a previously allocated block
* @param ptr pointer to the memory that needs to be released
* @return none
*/
extern void VMPI_free(void* ptr);
/**
* This method is used to free a previously allocated block
* @param ptr pointer to the memory that needs to be released
* @return none
*/
extern size_t VMPI_size(void* ptr);
/**
* This method is used to get the size of the memory page of the system
* @return return the size, if bytes, of memory page
*/
extern size_t VMPI_getVMPageSize();
/**
* Method to retrieve number of VM pages in virtual address space of a process
* @return number of pages
* @see VMPI_getVMPageSize()
*/
extern size_t VMPI_getPrivateResidentPageCount();
/**
* Method to find whether the platform supports merging of contiguous memory regions from heap
* @return true if heap merging is supported, false otherwise
*/
extern bool VMPI_canMergeContiguousHeapRegions();
/**
* This method is used to reserve region(s) of memory, i.e. one or more memory pages, in the system's virtual address space
* This method is recommended to be supported on platforms with virtual memory
* @param address optional argument, indicating the base address of the region to be reserved.
* The system should treat this address as a hint and try to reserve a region as close to this address as possible
* If NULL, the system can determine the address of the region.
* @param size size of region, in bytes, to reserve
* @return point to base address of the reserved region, NULL otherwise
* @see VMPI_ReleaseMemoryRegion(), VMPI_CommitMemory()
*/
extern void* VMPI_reserveMemoryRegion(void* address, size_t size);
/**
* This method is called to release region(s) of memory previously reserved.
* @param address base address of the region to be released
* @param size size, in bytes, of the region
* @return true if the function succeeds, false otherwise
*/
extern bool VMPI_releaseMemoryRegion(void* address, size_t size);
/**
* This method is used to commit a pages(s) of memory in a previously reserved region
* @param address base address of the memory region to commit
* @param size size, in bytes, of the memory to commit
* @return true if the function succeeds, false otherwise
* @see VMPI_ReserveMemoryRegion()
*/
extern bool VMPI_commitMemory(void* address, size_t size);
/**
* This method is used to de-commit a pages(s) of memory that were previously commited
* @param address base address of the memory region to decommit
* @param size, in bytes, of the memory region to decommit
* @return true if the function succeeds, false otherwise
* @see VMPI_CommitMemory()
*/
extern bool VMPI_decommitMemory(char *address, size_t size);
/**
* SetPageProtection changes the page access protections on a block of pages,
* to make JIT-ted code executable or not.
*
* @param address pointer to start of memory block. It is possible that the memory block pointed to by address
* could be acquired from more than one calls to VMPI_reserveMemoryRegion. The implementation of this method
* is expected to handle such cases and identify the region boundaries if the underlying system requires
* setting the protection flags on blocks individually if they were allocated separately.
* @param executableFlag If executableFlag is true, the memory is made executable and read-only.
* If executableFlag is false, the memory is made non-executable and read-write.
* @param writeableFlag If true memory block is made read-write
*/
extern void VMPI_setPageProtection(void *address, size_t size, bool executeFlag, bool writeableFlag);
/**
* This method is used to allocate a block of memory with the base address aligned to the system page size
* This method should be implemented in systems that do not have virtual memory in lieu of APIs to reserve and commit memory regions
* @param size size, in bytes, of the block of memory to allocate
* @return pointer to start of the memory block if allocation was successful, NULL otherwise
* @see VMPI_ReleaseAlignedMemory()
*/
extern void* VMPI_allocateAlignedMemory(size_t size);
/**
* This method is used to release a block of memory via VMPI_AllocateAlignedMemory
* @param address pointer to the start of the memory block to be released
* @return none
*/
extern void VMPI_releaseAlignedMemory(void* address);
/**
* This method is used to determind should MMgc zero initalize newly allocated memory,
* either allocated with VMPI_commitMemory or VMPI_allocateAlignedMemory.
* @return false if the memory is zero initialized by the OS, otherwise true
*/
extern bool VMPI_areNewPagesDirty();
/**
* Method to get the frequency of a high performance counter/timer on the system
* On platforms where no API to retrieve this information should return a number that closely
* matches its timer frequency
* @return 64-bit value indicating the frequency of the system's performance counter or clock with highest resolution
* @see VMPI_getPerformanceCounter()
*/
extern uint64_t VMPI_getPerformanceFrequency();
/**
* Method to get the current value of the system's performance counter/timer
* Platforms that support a high performance counter should return its current value
* Platforms that do not have a high performance counter should return the current timer/clock
* value that was used as a basis to calculate the frequency returned from VMPI_getPerformanceFrequency()
* @return 64-bit value indicating the current value of the counter
* @see VMPI_getPerformanceFrequency()
*/extern uint64_t VMPI_getPerformanceCounter();
/**
* Method to obtain the stack backtrace
* Used by the MMgc memory profiler to get call stack information
* @param buffer buffer to fill the call stack data with
* @param bufferSize size, in bytes, of the buffer passed
* @param framesToSkip number of function frames to skip from the start of trace
* @return true if back trace was captured successfully, false otherwise
*/
extern bool VMPI_captureStackTrace(uintptr_t* buffer, size_t bufferSize, uint32_t framesToSkip);
/**
* Method to retrieve the name of the method/function given a specific address in code space
* Used by the MMgc memory profiler to get and display function names
* This method is expected to write a null terminated string representing the function name
* in to the buffer
* @param pc address whose corresponding function name should be returned
* @param buffer buffer to write the function name to
* @param bufferSize size, in bytes, of the buffer passed
* @return true if the function name was retrieved, false otherwise
*/
extern bool VMPI_getFunctionNameFromPC(uintptr_t pc, char *buffer, size_t bufferSize);
/**
* Method to retrieve the source filename and line number given a specific address in a code space
* Used by the MMgc memory profiler to display location info of source code
* This method is expected to write a null terminated string representing the file name
* in to the buffer
* @param pc address of code whose corresponding location should be returned
* @param buffer buffer to write the filename to
* @param bufferSize size, in bytes, of the buffer for filename
* @param out param to write the line number to
* @return true if the file and line number info was retrieved successfully, false otherwise
*/
extern bool VMPI_getFileAndLineInfoFromPC(uintptr_t pc, char *buffer, size_t bufferSize, uint32_t* lineNumber);
/**
* Method to create a new instance of vmpi_spin_lock_t
* This instance will subsequently be passed to acquire/release lock methods
* @return newly created vmpi_spin_lock_t instance
*/
extern void VMPI_lockInit(vmpi_spin_lock_t* lock);
/**
* Method to destroy the vmpi_spin_lock_t instance
* This method is called when MMgc no longer intends to use the vmpi_spin_lock_t
* instance created and return via VMPI_lockCreate.
* The implementation can safely destroy the lock instance.
* It is allowed for the caller to have acquired the lock when this function is called.
* @param lock instance of vmpi_spin_lock_t to be destroyed
* @return none
* @see VMPI_lockCreate
*/
extern void VMPI_lockDestroy(vmpi_spin_lock_t* lock);
/**
* Method to acquire a lock on a vmpi_spin_lock_t instance
* If this method returns true, MMgc assumes that the lock was acquired successfully
* During a call to this method, if the lock was held by some other thread then the
* implementation should wait until the lock becomes available
* Return value of false is considered to be an error condition and should only happen
* in exception situations
* @param lock instance to acquire the lock on
* @return true if lock was successfully acquired, false in event of failure
*/
extern bool VMPI_lockAcquire(vmpi_spin_lock_t* lock);
/**
* Method to release a lock on a vmpi_spin_lock_t instance
* @param lock instance to release the lock on
* @return true if lock was successfully release, false in event of failure
*/
extern bool VMPI_lockRelease(vmpi_spin_lock_t* lock);
/**
* Method to obtain a lock on a vmpi_spin_lock_t instance if it isn't locked
* @param lock instance to release the lock on
* @return true if lock was successfully aqcuired, false if another thread has it
*/
extern bool VMPI_lockTestAndAcquire(vmpi_spin_lock_t* lock);
/**
* can two consecutive calls to VMPI_reserveMemoryRegion be freed with one VMP_releaseMemoryRegion call?
* @return true if it can
*/
extern bool VMPI_canMergeContiguousRegions();
/**
* are the virtual memory API's implemented and usable for this platform/OS?
* @return true if they are
*/
extern bool VMPI_useVirtualMemory();
/**
* Method to check whether MMgc memory profiling is turned on or not
* @return true if profiling is enabled, false otherwise
*/
extern bool VMPI_isMemoryProfilingEnabled();
/**
* Method to setup a spy channel on MMgc/avmplus
* If the platform intends to periodically retrieve information from MMgc/avmplus
* then it can perform the necessary setup during this function call and return true
* @return true if the spy is setup successfully else false
* @see VMPI_spyCallback
*/
extern bool VMPI_spySetup();
/**
* Callback method for spy
* Currently called on every allocation in MMgc if VMPI_spySetup returned true
* @return none
*/
extern void VMPI_spyCallback();
/**
* Clean from the current stack pointer amt bytes
* @param the amout of bytes to clear
*/
extern void VMPI_cleanStack(size_t amt);
/**
* MEthod to determine whether we have access to symbol information
* @return a bool indicating whether we have
*/
extern bool VMPI_hasSymbols();
/**
* Method to create a thread local storage (TLS) identifier
* This identifier will be used as a key to set/get thread-specific data
* @param [out] pointer to store the value of newly created TLS identifier
* @return true if TLS identifier was created successfully, false otherwise
*/
extern bool VMPI_tlsCreate(uintptr_t* tlsId);
/**
* Method to destroy a previously created TLS identifier
* @param tlsId TLS identifier to be destroyed
* @return none
* @see VMPI_tlsCreate()
*/
extern void VMPI_tlsDestroy(uintptr_t tlsId);
/**
* Method to associate a thread-specific data with a TLS identifier
* previously created by VMPI_tlsCreate
* @param tlsId TLS identifier to associate the data with
* @param value data to be associated with id
* @return true if value was set successfully, false otherwise
*/
extern bool VMPI_tlsSetValue(uintptr_t tlsId, void* value);
/**
* Method to retrieve a data associated with a TLS identifier
* that may have been previously set via VMPI_tlsSetValue
* @param tlsId TLS identifier for which the associated data should be retrieved
* @return the associated data, else NULL if no value was set
* @see VMPI_tlsSetValue
*/
extern void* VMPI_tlsGetValue(uintptr_t tlsId);
/**
* Obtain current thread identifier
* @return thread id
*/
extern vmpi_thread_t VMPI_currentThread();
/**
* Method to setup a spy channel on MMgc/avmplus
* If the platform intends to periodically retrieve information from MMgc/avmplus
* then it can perform the necessary setup during this function call and return true
* @return true if the spy is setup successfully else false
* @see VMPI_spyCallback
*/
extern bool VMPI_spySetup();
extern void VMPI_spyTeardown();
/**
* Callback method for spy
* Currently called on every allocation in MMgc if VMPI_spySetup returned true
* @return none
*/
extern void VMPI_spyCallback();
/*
* Method to perform any initialization activities to assist
* the program counter to symbols resolution for MMgc memory profiler
* @return none
*/
extern void VMPI_setupPCResolution();
/**
* Method to perform any cleanup of items that were created/setup
* for program counter to symbols resolution for MMgc memory profiler
* @return none
* @see VMPI_setupPCResolution
*/
extern void VMPI_desetupPCResolution();
/**
* wrapper around getenv function, return's NULL on platforms with no env vars
* @return value of env var
*/
extern const char *VMPI_getenv(const char *name);
#endif /* __avmplus_VMPI__ */