mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-26 09:58:20 +01:00
use a reference to a byte array in the java heap (locking down the
object) rather than allocating a new array in the C heap -- for the DAWG data of a dictionary. This can use up to 5% of the java heap for huge dictionaries, but I'm hoping it fixes a problem reported by a user of the large German dictionary that seems to involve allocation. If I'm reading correctly, as long as I stay within 16M (24M or more on newer devices) I'm sure to get my memory in the java world while it's less a sure thing in the JNI world (where in addition linux's aggressive overallocation is used, meaning I'll fail when I try to swap in memory on write rather than get back NULL from malloc.)
This commit is contained in:
parent
49cdb7e629
commit
b722cc5f65
1 changed files with 18 additions and 22 deletions
|
@ -34,7 +34,8 @@ typedef struct _AndDictionaryCtxt {
|
||||||
DictionaryCtxt super;
|
DictionaryCtxt super;
|
||||||
JNIUtilCtxt* jniutil;
|
JNIUtilCtxt* jniutil;
|
||||||
JNIEnv *env;
|
JNIEnv *env;
|
||||||
XP_U8* bytes;
|
jbyte* bytes;
|
||||||
|
jbyteArray byteArray;
|
||||||
} AndDictionaryCtxt;
|
} AndDictionaryCtxt;
|
||||||
|
|
||||||
static void splitFaces_via_java( JNIEnv* env, AndDictionaryCtxt* ctxt,
|
static void splitFaces_via_java( JNIEnv* env, AndDictionaryCtxt* ctxt,
|
||||||
|
@ -51,7 +52,7 @@ dict_splitFaces( DictionaryCtxt* dict, const XP_U8* bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
static XP_U32
|
static XP_U32
|
||||||
n_ptr_tohl( XP_U8** inp )
|
n_ptr_tohl( XP_U8 const** inp )
|
||||||
{
|
{
|
||||||
XP_U32 t;
|
XP_U32 t;
|
||||||
XP_MEMCPY( &t, *inp, sizeof(t) );
|
XP_MEMCPY( &t, *inp, sizeof(t) );
|
||||||
|
@ -62,7 +63,7 @@ n_ptr_tohl( XP_U8** inp )
|
||||||
} /* n_ptr_tohl */
|
} /* n_ptr_tohl */
|
||||||
|
|
||||||
static XP_U16
|
static XP_U16
|
||||||
n_ptr_tohs( XP_U8** inp )
|
n_ptr_tohs( XP_U8 const ** inp )
|
||||||
{
|
{
|
||||||
XP_U16 t;
|
XP_U16 t;
|
||||||
XP_MEMCPY( &t, *inp, sizeof(t) );
|
XP_MEMCPY( &t, *inp, sizeof(t) );
|
||||||
|
@ -88,9 +89,9 @@ andCountSpecials( AndDictionaryCtxt* ctxt )
|
||||||
} /* andCountSpecials */
|
} /* andCountSpecials */
|
||||||
|
|
||||||
static XP_Bitmap
|
static XP_Bitmap
|
||||||
andMakeBitmap( AndDictionaryCtxt* ctxt, XP_U8** ptrp )
|
andMakeBitmap( AndDictionaryCtxt* ctxt, XP_U8 const** ptrp )
|
||||||
{
|
{
|
||||||
XP_U8* ptr = *ptrp;
|
XP_U8 const* ptr = *ptrp;
|
||||||
XP_U8 nCols = *ptr++;
|
XP_U8 nCols = *ptr++;
|
||||||
jobject bitmap = NULL;
|
jobject bitmap = NULL;
|
||||||
|
|
||||||
|
@ -134,10 +135,10 @@ andMakeBitmap( AndDictionaryCtxt* ctxt, XP_U8** ptrp )
|
||||||
} /* andMakeBitmap */
|
} /* andMakeBitmap */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
andLoadSpecialData( AndDictionaryCtxt* ctxt, XP_U8** ptrp )
|
andLoadSpecialData( AndDictionaryCtxt* ctxt, XP_U8 const** ptrp )
|
||||||
{
|
{
|
||||||
XP_U16 nSpecials = andCountSpecials( ctxt );
|
XP_U16 nSpecials = andCountSpecials( ctxt );
|
||||||
XP_U8* ptr = *ptrp;
|
XP_U8 const* ptr = *ptrp;
|
||||||
Tile ii;
|
Tile ii;
|
||||||
XP_UCHAR** texts;
|
XP_UCHAR** texts;
|
||||||
SpecialBitmaps* bitmaps;
|
SpecialBitmaps* bitmaps;
|
||||||
|
@ -230,7 +231,7 @@ splitFaces_via_java( JNIEnv* env, AndDictionaryCtxt* ctxt, const XP_U8* ptr,
|
||||||
} /* splitFaces_via_java */
|
} /* splitFaces_via_java */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parseDict( AndDictionaryCtxt* ctxt, XP_U8* ptr, XP_U32 dictLength )
|
parseDict( AndDictionaryCtxt* ctxt, XP_U8 const* ptr, XP_U32 dictLength )
|
||||||
{
|
{
|
||||||
while( !!ptr ) { /* lets us break.... */
|
while( !!ptr ) { /* lets us break.... */
|
||||||
XP_U32 offset;
|
XP_U32 offset;
|
||||||
|
@ -363,6 +364,7 @@ and_dictionary_destroy( DictionaryCtxt* dict )
|
||||||
AndDictionaryCtxt* ctxt = (AndDictionaryCtxt*)dict;
|
AndDictionaryCtxt* ctxt = (AndDictionaryCtxt*)dict;
|
||||||
XP_U16 nSpecials = andCountSpecials( ctxt );
|
XP_U16 nSpecials = andCountSpecials( ctxt );
|
||||||
XP_U16 ii;
|
XP_U16 ii;
|
||||||
|
JNIEnv* env = ctxt->env;
|
||||||
|
|
||||||
if ( !!ctxt->super.chars ) {
|
if ( !!ctxt->super.chars ) {
|
||||||
for ( ii = 0; ii < nSpecials; ++ii ) {
|
for ( ii = 0; ii < nSpecials; ++ii ) {
|
||||||
|
@ -374,7 +376,6 @@ and_dictionary_destroy( DictionaryCtxt* dict )
|
||||||
XP_FREE( ctxt->super.mpool, ctxt->super.chars );
|
XP_FREE( ctxt->super.mpool, ctxt->super.chars );
|
||||||
}
|
}
|
||||||
if ( !!ctxt->super.bitmaps ) {
|
if ( !!ctxt->super.bitmaps ) {
|
||||||
JNIEnv* env = ctxt->env;
|
|
||||||
for ( ii = 0; ii < nSpecials; ++ii ) {
|
for ( ii = 0; ii < nSpecials; ++ii ) {
|
||||||
jobject bitmap = ctxt->super.bitmaps[ii].largeBM;
|
jobject bitmap = ctxt->super.bitmaps[ii].largeBM;
|
||||||
if ( !!bitmap ) {
|
if ( !!bitmap ) {
|
||||||
|
@ -391,7 +392,8 @@ and_dictionary_destroy( DictionaryCtxt* dict )
|
||||||
XP_FREE( ctxt->super.mpool, ctxt->super.name );
|
XP_FREE( ctxt->super.mpool, ctxt->super.name );
|
||||||
}
|
}
|
||||||
|
|
||||||
XP_FREE( ctxt->super.mpool, ctxt->bytes );
|
(*env)->ReleaseByteArrayElements( env, ctxt->byteArray, ctxt->bytes, 0 );
|
||||||
|
(*env)->DeleteGlobalRef( env, ctxt->byteArray );
|
||||||
XP_FREE( ctxt->super.mpool, ctxt );
|
XP_FREE( ctxt->super.mpool, ctxt );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,23 +426,17 @@ DictionaryCtxt*
|
||||||
makeDict( MPFORMAL JNIEnv *env, JNIUtilCtxt* jniutil, jbyteArray jbytes,
|
makeDict( MPFORMAL JNIEnv *env, JNIUtilCtxt* jniutil, jbyteArray jbytes,
|
||||||
jstring jname )
|
jstring jname )
|
||||||
{
|
{
|
||||||
AndDictionaryCtxt* anddict = NULL;
|
AndDictionaryCtxt* anddict = (AndDictionaryCtxt*)
|
||||||
|
and_dictionary_make_empty( MPPARM(mpool) env, jniutil );
|
||||||
|
|
||||||
jsize len = (*env)->GetArrayLength( env, jbytes );
|
jsize len = (*env)->GetArrayLength( env, jbytes );
|
||||||
|
anddict->byteArray = (*env)->NewGlobalRef( env, jbytes );
|
||||||
|
anddict->bytes = (*env)->GetByteArrayElements( env, anddict->byteArray,
|
||||||
|
NULL );
|
||||||
|
|
||||||
XP_U8* localBytes = XP_MALLOC( mpool, len );
|
|
||||||
jbyte* src = (*env)->GetByteArrayElements( env, jbytes, NULL );
|
|
||||||
XP_MEMCPY( localBytes, src, len );
|
|
||||||
(*env)->ReleaseByteArrayElements( env, jbytes, src, 0 );
|
|
||||||
|
|
||||||
anddict = (AndDictionaryCtxt*)
|
|
||||||
and_dictionary_make_empty( MPPARM(mpool) env, jniutil );
|
|
||||||
anddict->super.destructor = and_dictionary_destroy;
|
anddict->super.destructor = and_dictionary_destroy;
|
||||||
/* anddict->super.func_dict_getShortName = and_dict_getShortName; */
|
|
||||||
|
|
||||||
anddict->bytes = localBytes;
|
parseDict( anddict, (XP_U8*)anddict->bytes, len );
|
||||||
|
|
||||||
parseDict( anddict, localBytes, len );
|
|
||||||
|
|
||||||
/* copy the name */
|
/* copy the name */
|
||||||
if ( NULL != jname ) {
|
if ( NULL != jname ) {
|
||||||
|
|
Loading…
Reference in a new issue