Merge pull request #419 from dicej/type-generator-limit

handle arbitrary class sizes in type-generator/main.cpp
This commit is contained in:
Joshua Warner 2015-03-12 13:33:42 -06:00
commit 7a74c2c168
5 changed files with 83 additions and 18 deletions

View File

@ -23,7 +23,7 @@
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
#
# Define public interface.
@ -159,6 +159,7 @@ SUNWprivate_1.1 {
JVM_GetMethodParameterAnnotations;
JVM_GetPrimitiveArrayElement;
JVM_GetProtectionDomain;
JVM_GetResourceLookupCacheURLs;
JVM_GetSockName;
JVM_GetSockOpt;
JVM_GetStackAccessControlContext;
@ -291,4 +292,3 @@ SUNWprivate_1.1 {
# This is for Forte Analyzer profiling support.
AsyncGetCallTrace;
};

View File

@ -441,6 +441,11 @@ class MyClasspath : public Classpath {
setObjectClass(t, c, type(t, GcJclass::Type));
c->setName(t, name);
c->setVmClass(t, class_);
#ifdef HAVE_JclassClassLoader
if (class_->loader() != roots(t)->bootLoader()) {
c->setClassLoader(t, class_->loader());
}
#endif
return c;
}
@ -4564,6 +4569,12 @@ extern "C" AVIAN_EXPORT jobject JNICALL
return reinterpret_cast<jobject>(run(t, jvmGetProtectionDomain, arguments));
}
extern "C" AVIAN_EXPORT jobject JNICALL
EXPORT(JVM_GetResourceLookupCacheURLs)(Thread*, jobject)
{
return 0;
}
extern "C" AVIAN_EXPORT void JNICALL
EXPORT(JVM_SetProtectionDomain)(Thread*, jclass, jobject)
{

View File

@ -3101,7 +3101,7 @@ void removeString(Thread* t, object o)
void bootClass(Thread* t,
Gc::Type type,
int superType,
uint32_t objectMask,
uint32_t* objectMask,
unsigned fixedSize,
unsigned arrayElementSize,
unsigned vtableLength)
@ -3109,15 +3109,20 @@ void bootClass(Thread* t,
GcClass* super
= (superType >= 0 ? vm::type(t, static_cast<Gc::Type>(superType)) : 0);
unsigned maskSize
= ceilingDivide(fixedSize + arrayElementSize, 32 * BytesPerWord);
GcIntArray* mask;
if (objectMask) {
if (super and super->objectMask()
and super->objectMask()->body()[0]
== static_cast<int32_t>(objectMask)) {
and super->objectMask()->length() == maskSize
and memcmp(super->objectMask()->body().begin(),
objectMask,
sizeof(uint32_t) * maskSize) == 0) {
mask = vm::type(t, static_cast<Gc::Type>(superType))->objectMask();
} else {
mask = makeIntArray(t, 1);
mask->body()[0] = objectMask;
mask = makeIntArray(t, maskSize);
memcpy(mask->body().begin(), objectMask, sizeof(uint32_t) * maskSize);
}
} else {
mask = 0;

View File

@ -120,7 +120,7 @@ class Output {
virtual void write(const std::string& s) = 0;
void write(int i)
void write(int32_t i)
{
static const int Size = 32;
char s[Size];
@ -128,6 +128,15 @@ class Output {
assert(c > 0 and c < Size);
write(s);
}
void writeUnsigned(uint32_t i)
{
static const int Size = 32;
char s[Size];
int c UNUSED = vm::snprintf(s, Size, "%u", i);
assert(c > 0 and c < Size);
write(s);
}
};
class FileOutput : public Output {

View File

@ -25,6 +25,7 @@
#include <avian/util/arg-parser.h>
#include <avian/util/stream.h>
#include <avian/util/math.h>
#include "io.h"
#include "sexpr.h"
@ -1326,17 +1327,23 @@ void set(uint32_t* mask, unsigned index)
}
}
uint32_t typeObjectMask(Module& module, Class* cl)
void set(std::vector<uint32_t>& mask, unsigned index)
{
assert(cl->fixedSize + (cl->arrayField ? cl->arrayField->elementSize : 0)
< 32 * BytesPerWord);
set(&(mask[index / 32]), index % 32);
}
uint32_t mask = 1;
std::vector<uint32_t> typeObjectMask(Module& module, Class* cl)
{
std::vector<uint32_t> mask(ceilingDivide(
cl->fixedSize + (cl->arrayField ? cl->arrayField->elementSize : 0),
32 * BytesPerWord));
set(mask, 0);
for (const auto f : cl->fields) {
unsigned offset = f->offset / BytesPerWord;
if (isFieldGcVisible(module, f)) {
set(&mask, offset);
set(mask, offset);
}
}
@ -1344,13 +1351,28 @@ uint32_t typeObjectMask(Module& module, Class* cl)
Field* f = cl->arrayField;
unsigned offset = f->offset / BytesPerWord;
if (isFieldGcVisible(module, f)) {
set(&mask, offset);
set(mask, offset);
}
}
return mask;
}
bool trivialMask(const std::vector<uint32_t>& mask)
{
if (mask[0] != 1) {
return false;
}
for (size_t i = 1; i < mask.size(); ++i) {
if (mask[i]) {
return false;
}
}
return true;
}
void writeInitialization(Output* out,
Module& module,
std::set<Class*>& alreadyInited,
@ -1363,6 +1385,24 @@ void writeInitialization(Output* out,
if (cl->super && cl->name != "intArray" && cl->name != "class") {
writeInitialization(out, module, alreadyInited, cl->super);
}
std::vector<uint32_t> mask = typeObjectMask(module, cl);
bool trivialMask = local::trivialMask(mask);
if (trivialMask) {
out->write("{ ");
} else {
out->write("{ uint32_t mask[");
out->write(mask.size());
out->write("] = { ");
for (size_t i = 0; i < mask.size(); ++i) {
out->writeUnsigned(mask[i]);
if (i < mask.size() - 1) {
out->write(", ");
}
}
out->write(" };\n");
}
out->write("bootClass(t, Gc::");
out->write(capitalize(cl->name));
out->write("Type, ");
@ -1376,10 +1416,10 @@ void writeInitialization(Output* out,
}
out->write(", ");
if (typeObjectMask(module, cl) != 1) {
out->write(typeObjectMask(module, cl));
} else {
if (trivialMask) {
out->write("0");
} else {
out->write("mask");
}
out->write(", ");
@ -1390,7 +1430,7 @@ void writeInitialization(Output* out,
out->write(", ");
out->write(cl->methods.size());
out->write(");\n");
out->write("); }\n");
}
void writeInitializations(Output* out, Module& module)