|  | /* | 
|  | * Copyright (C) 2008 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  | /* | 
|  | * Simple linear memory allocator. | 
|  | */ | 
|  | #ifndef _DALVIK_LINEARALLOC | 
|  | #define _DALVIK_LINEARALLOC | 
|  |  | 
|  | /* | 
|  | * If this is set, we create additional data structures and make many | 
|  | * additional mprotect() calls. | 
|  | */ | 
|  | #define ENFORCE_READ_ONLY   false | 
|  |  | 
|  | /* | 
|  | * Linear allocation state.  We could tuck this into the start of the | 
|  | * allocated region, but that would prevent us from sharing the rest of | 
|  | * that first page. | 
|  | */ | 
|  | typedef struct LinearAllocHdr { | 
|  | int     curOffset;          /* offset where next data goes */ | 
|  | pthread_mutex_t lock;       /* controls updates to this struct */ | 
|  |  | 
|  | char*   mapAddr;            /* start of mmap()ed region */ | 
|  | int     mapLength;          /* length of region */ | 
|  | int     firstOffset;        /* for chasing through */ | 
|  |  | 
|  | short*  writeRefCount;      /* for ENFORCE_READ_ONLY */ | 
|  | } LinearAllocHdr; | 
|  |  | 
|  |  | 
|  | /* | 
|  | * Create a new alloc region. | 
|  | */ | 
|  | LinearAllocHdr* dvmLinearAllocCreate(Object* classLoader); | 
|  |  | 
|  | /* | 
|  | * Destroy a region. | 
|  | */ | 
|  | void dvmLinearAllocDestroy(Object* classLoader); | 
|  |  | 
|  | /* | 
|  | * Allocate a chunk of memory.  The memory will be zeroed out. | 
|  | * | 
|  | * For ENFORCE_READ_ONLY, call dvmLinearReadOnly on the result. | 
|  | */ | 
|  | void* dvmLinearAlloc(Object* classLoader, size_t size); | 
|  |  | 
|  | /* | 
|  | * Reallocate a chunk.  The original storage is not released, but may be | 
|  | * erased to aid debugging. | 
|  | * | 
|  | * For ENFORCE_READ_ONLY, call dvmLinearReadOnly on the result.  Also, the | 
|  | * caller should probably mark the "mem" argument read-only before calling. | 
|  | */ | 
|  | void* dvmLinearRealloc(Object* classLoader, void* mem, size_t newSize); | 
|  |  | 
|  | /* don't call these directly */ | 
|  | void dvmLinearSetReadOnly(Object* classLoader, void* mem); | 
|  | void dvmLinearSetReadWrite(Object* classLoader, void* mem); | 
|  |  | 
|  | /* | 
|  | * Mark a chunk of memory from Alloc or Realloc as read-only.  This must | 
|  | * be done after all changes to the block of memory have been made.  This | 
|  | * actually operates on a page granularity. | 
|  | */ | 
|  | INLINE void dvmLinearReadOnly(Object* classLoader, void* mem) | 
|  | { | 
|  | if (ENFORCE_READ_ONLY && mem != NULL) | 
|  | dvmLinearSetReadOnly(classLoader, mem); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Make a chunk of memory writable again. | 
|  | */ | 
|  | INLINE void dvmLinearReadWrite(Object* classLoader, void* mem) | 
|  | { | 
|  | if (ENFORCE_READ_ONLY && mem != NULL) | 
|  | dvmLinearSetReadWrite(classLoader, mem); | 
|  | } | 
|  |  | 
|  | /* | 
|  | * Free a chunk.  Does not increase available storage, but the freed area | 
|  | * may be erased to aid debugging. | 
|  | */ | 
|  | void dvmLinearFree(Object* classLoader, void* mem); | 
|  |  | 
|  | /* | 
|  | * Helper function; allocates new storage and copies "str" into it. | 
|  | * | 
|  | * For ENFORCE_READ_ONLY, do *not* call dvmLinearReadOnly on the result. | 
|  | * This is done automatically. | 
|  | */ | 
|  | char* dvmLinearStrdup(Object* classLoader, const char* str); | 
|  |  | 
|  | /* | 
|  | * Dump the contents of a linear alloc area. | 
|  | */ | 
|  | void dvmLinearAllocDump(Object* classLoader); | 
|  |  | 
|  | /* | 
|  | * Determine if [start, start+length) is contained in the in-use area of | 
|  | * a single LinearAlloc.  The full set of linear allocators is scanned. | 
|  | */ | 
|  | bool dvmLinearAllocContains(const void* start, size_t length); | 
|  |  | 
|  | #endif /*_DALVIK_LINEARALLOC*/ |