mirror of
https://github.com/corda/corda.git
synced 2025-01-22 12:28:11 +00:00
453ceb42ab
Unlike the interpreter, the JIT compiler tries to resolve all the symbols referenced by a method when compiling that method. However, this can backfire if a symbol cannot be resolved: we end up throwing an e.g. NoClassDefFoundError for code which may never be executed. This is particularly troublesome for code which supports multiple APIs, choosing one at runtime. The solution is to defer to stub code for symbols which can't be resolved at JIT compile time. Such a stub will try again at runtime to resolve the needed symbol and throw an appropriate error if it still can't be found.
160 lines
3.2 KiB
C++
160 lines
3.2 KiB
C++
/* Copyright (c) 2008-2009, Avian Contributors
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
for any purpose with or without fee is hereby granted, provided
|
|
that the above copyright notice and this permission notice appear
|
|
in all copies.
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
details. */
|
|
|
|
#ifndef VECTOR_H
|
|
#define VECTOR_H
|
|
|
|
#include "system.h"
|
|
|
|
namespace vm {
|
|
|
|
class Vector {
|
|
public:
|
|
Vector(System* s, Allocator* allocator, unsigned minimumCapacity):
|
|
s(s),
|
|
allocator(allocator),
|
|
data(0),
|
|
position(0),
|
|
capacity(0),
|
|
minimumCapacity(minimumCapacity)
|
|
{ }
|
|
|
|
~Vector() {
|
|
dispose();
|
|
}
|
|
|
|
void dispose() {
|
|
if (data and minimumCapacity >= 0) {
|
|
allocator->free(data, capacity);
|
|
data = 0;
|
|
}
|
|
}
|
|
|
|
void wrap(uint8_t* data, unsigned capacity) {
|
|
dispose();
|
|
|
|
this->data = data;
|
|
this->position = 0;
|
|
this->capacity = capacity;
|
|
this->minimumCapacity = -1;
|
|
}
|
|
|
|
void ensure(unsigned space) {
|
|
if (position + space > capacity) {
|
|
assert(s, minimumCapacity >= 0);
|
|
|
|
unsigned newCapacity = max
|
|
(position + space, max(minimumCapacity, capacity * 2));
|
|
uint8_t* newData = static_cast<uint8_t*>
|
|
(allocator->allocate(newCapacity));
|
|
if (data) {
|
|
memcpy(newData, data, position);
|
|
allocator->free(data, capacity);
|
|
}
|
|
data = newData;
|
|
capacity = newCapacity;
|
|
}
|
|
}
|
|
|
|
void get(unsigned offset, void* dst, unsigned size) {
|
|
assert(s, offset + size <= position);
|
|
memcpy(dst, data + offset, size);
|
|
}
|
|
|
|
void set(unsigned offset, const void* src, unsigned size) {
|
|
assert(s, offset + size <= position);
|
|
memcpy(data + offset, src, size);
|
|
}
|
|
|
|
void pop(void* dst, unsigned size) {
|
|
get(position - size, dst, size);
|
|
position -= size;
|
|
}
|
|
|
|
void* allocate(unsigned size) {
|
|
ensure(size);
|
|
void* r = data + position;
|
|
position += size;
|
|
return r;
|
|
}
|
|
|
|
void* append(const void* p, unsigned size) {
|
|
void* r = allocate(size);
|
|
memcpy(r, p, size);
|
|
return r;
|
|
}
|
|
|
|
void append(uint8_t v) {
|
|
append(&v, 1);
|
|
}
|
|
|
|
void append2(uint16_t v) {
|
|
append(&v, 2);
|
|
}
|
|
|
|
void append4(uint32_t v) {
|
|
append(&v, 4);
|
|
}
|
|
|
|
void appendAddress(uintptr_t v) {
|
|
append(&v, BytesPerWord);
|
|
}
|
|
|
|
void appendAddress(void* v) {
|
|
append(&v, BytesPerWord);
|
|
}
|
|
|
|
void set2(unsigned offset, uint16_t v) {
|
|
assert(s, offset <= position - 2);
|
|
memcpy(data + offset, &v, 2);
|
|
}
|
|
|
|
unsigned get(unsigned offset) {
|
|
uint8_t v; get(offset, &v, 1);
|
|
return v;
|
|
}
|
|
|
|
unsigned get2(unsigned offset) {
|
|
uint16_t v; get(offset, &v, 2);
|
|
return v;
|
|
}
|
|
|
|
unsigned get4(unsigned offset) {
|
|
uint32_t v; get(offset, &v, 4);
|
|
return v;
|
|
}
|
|
|
|
uintptr_t getAddress(unsigned offset) {
|
|
uintptr_t v; get(offset, &v, BytesPerWord);
|
|
return v;
|
|
}
|
|
|
|
unsigned length() {
|
|
return position;
|
|
}
|
|
|
|
template <class T>
|
|
T* peek(unsigned offset) {
|
|
assert(s, offset + sizeof(T) <= position);
|
|
return reinterpret_cast<T*>(data + offset);
|
|
}
|
|
|
|
System* s;
|
|
Allocator* allocator;
|
|
uint8_t* data;
|
|
unsigned position;
|
|
unsigned capacity;
|
|
int minimumCapacity;
|
|
};
|
|
|
|
} // namespace vm
|
|
|
|
#endif//VECTOR_H
|