Skip to content

Commit

Permalink
Speed up non-specialized frame creation.
Browse files Browse the repository at this point in the history
By having an initial work environment that we can memcpy into place
rather than having to look at what needs to be set to VMNull every
time. Still to do for specialized frames.
  • Loading branch information
jnthn committed May 13, 2016
1 parent 973592c commit 5d854b2
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 34 deletions.
1 change: 1 addition & 0 deletions src/6model/reprs/MVMStaticFrame.c
Expand Up @@ -184,6 +184,7 @@ static void gc_free(MVMThreadContext *tc, MVMObject *obj) {
if (!body->fully_deserialized)
return;
MVM_free(body->handlers);
MVM_free(body->work_initial);
MVM_free(body->static_env);
MVM_free(body->static_env_flags);
MVM_free(body->local_types);
Expand Down
4 changes: 4 additions & 0 deletions src/6model/reprs/MVMStaticFrame.h
Expand Up @@ -49,6 +49,10 @@ struct MVMStaticFrameBody {
/* The size in bytes to allocate for the work and arguments area. */
MVMuint32 work_size;

/* Inital contents of the work area, copied into place to make sure we have
* VMNulls in all the object slots. */
MVMRegister *work_initial;

/* The size of the bytecode. */
MVMuint32 bytecode_size;

Expand Down
78 changes: 44 additions & 34 deletions src/core/frame.c
@@ -1,5 +1,16 @@
#include "moar.h"

/* Computes the initial work area for a frame or a specialization of a frame. */
MVMRegister * MVM_frame_initial_work(MVMThreadContext *tc, MVMuint16 *local_types,
MVMuint16 num_locals) {
MVMuint16 i;
MVMRegister *work_initial = MVM_calloc(sizeof(MVMRegister), num_locals);
for (i = 0; i < num_locals; i++)
if (local_types[i] == MVM_reg_obj)
work_initial[i].o = tc->instance->VMNull;
return work_initial;
}

/* Takes a static frame and does various one-off calculations about what
* space it shall need. Also triggers bytecode verification of the frame's
* bytecode. */
Expand All @@ -26,6 +37,13 @@ static void prepare_and_verify_static_frame(MVMThreadContext *tc, MVMStaticFrame
/* Obtain an index to each threadcontext's lexotic pool table */
static_frame_body->pool_index = MVM_incr(&tc->instance->num_frames_run);

/* Compute work area initial state that we can memcpy into place each
* time. */
if (static_frame_body->num_locals)
static_frame_body->work_initial = MVM_frame_initial_work(tc,
static_frame_body->local_types,
static_frame_body->num_locals);

/* Check if we have any state var lexicals. */
if (static_frame_body->static_env_flags) {
MVMuint8 *flags = static_frame_body->static_env_flags;
Expand Down Expand Up @@ -205,32 +223,28 @@ static MVMFrame * allocate_frame(MVMThreadContext *tc, MVMStaticFrame *static_fr
}
work_size = spesh_cand ? spesh_cand->work_size : static_frame_body->work_size;
if (work_size) {
MVMuint32 i;
MVMuint32 num_locals;
MVMuint16 *local_types;

frame->work = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa, work_size);
frame->allocd_work = work_size;

/* Fill up all object registers with a pointer to our VMNull object */
if (spesh_cand && spesh_cand->local_types) {
num_locals = spesh_cand->num_locals;
local_types = spesh_cand->local_types;
MVMuint32 num_locals = spesh_cand->num_locals;
MVMuint16 *local_types = spesh_cand->local_types;
MVMuint32 i;
frame->work = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa, work_size);
for (i = 0; i < num_locals; i++)
if (local_types[i] == MVM_reg_obj)
frame->work[i].o = tc->instance->VMNull;
}
else {
num_locals = static_frame_body->num_locals;
local_types = static_frame_body->local_types;
frame->work = MVM_fixed_size_alloc(tc, tc->instance->fsa, work_size);
memcpy(frame->work, static_frame_body->work_initial,
sizeof(MVMRegister) * static_frame_body->num_locals);
}
for (i = 0; i < num_locals; i++)
if (local_types[i] == MVM_reg_obj)
frame->work[i].o = tc->instance->VMNull;
}
frame->allocd_work = work_size;

/* Calculate args buffer position. */
if (work_size)
/* Calculate args buffer position. */
frame->args = frame->work + (spesh_cand
? spesh_cand->num_locals
: static_frame_body->num_locals);
}

/* Assign a sequence nr */
frame->sequence_nr = tc->next_frame_nr++;
Expand Down Expand Up @@ -259,32 +273,28 @@ static MVMFrame * allocate_heap_frame(MVMThreadContext *tc, MVMStaticFrame *stat
}
work_size = spesh_cand ? spesh_cand->work_size : static_frame_body->work_size;
if (work_size) {
MVMuint32 i;
MVMuint32 num_locals;
MVMuint16 *local_types;

frame->work = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa, work_size);
frame->allocd_work = work_size;

/* Fill up all object registers with a pointer to our VMNull object */
if (spesh_cand && spesh_cand->local_types) {
num_locals = spesh_cand->num_locals;
local_types = spesh_cand->local_types;
MVMuint32 num_locals = spesh_cand->num_locals;
MVMuint16 *local_types = spesh_cand->local_types;
MVMuint32 i;
frame->work = MVM_fixed_size_alloc_zeroed(tc, tc->instance->fsa, work_size);
for (i = 0; i < num_locals; i++)
if (local_types[i] == MVM_reg_obj)
frame->work[i].o = tc->instance->VMNull;
}
else {
num_locals = static_frame_body->num_locals;
local_types = static_frame_body->local_types;
frame->work = MVM_fixed_size_alloc(tc, tc->instance->fsa, work_size);
memcpy(frame->work, static_frame_body->work_initial,
sizeof(MVMRegister) * static_frame_body->num_locals);
}
for (i = 0; i < num_locals; i++)
if (local_types[i] == MVM_reg_obj)
frame->work[i].o = tc->instance->VMNull;
}
frame->allocd_work = work_size;

/* Calculate args buffer position. */
if (work_size)
/* Calculate args buffer position. */
frame->args = frame->work + (spesh_cand
? spesh_cand->num_locals
: static_frame_body->num_locals);
}

return frame;
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/frame.h
Expand Up @@ -192,6 +192,8 @@ struct MVMInvocationSpec {
MVMString *md_valid_attr_name;
};

MVMRegister * MVM_frame_initial_work(MVMThreadContext *tc, MVMuint16 *local_types,
MVMuint16 num_locals);
void MVM_frame_destroy(MVMThreadContext *tc, MVMFrame *frame);
void MVM_frame_invoke_code(MVMThreadContext *tc, MVMCode *code,
MVMCallsite *callsite, MVMint32 spesh_cand);
Expand Down

0 comments on commit 5d854b2

Please sign in to comment.