Skip to content

Commit

Permalink
Preparations for deopt materialization
Browse files Browse the repository at this point in the history
* Stub in the data structures we'll use to describe materializations of
  replaced objects and what deopt points need them
* Add an NYI panic in deopt in the case that we encounter something to
  materialize (should never trigger at the moment)
  • Loading branch information
jnthn committed Nov 23, 2018
1 parent d1d6fbe commit 913504d
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/moar.h
Expand Up @@ -143,13 +143,13 @@ MVM_PUBLIC const MVMint32 MVM_jit_support(void);
#include "core/regionalloc.h"
#include "spesh/dump.h"
#include "spesh/debug.h"
#include "spesh/pea.h"
#include "spesh/graph.h"
#include "spesh/codegen.h"
#include "spesh/candidate.h"
#include "spesh/manipulate.h"
#include "spesh/args.h"
#include "spesh/usages.h"
#include "spesh/pea.h"
#include "spesh/facts.h"
#include "spesh/optimize.h"
#include "spesh/dead_bb_elimination.h"
Expand Down
2 changes: 2 additions & 0 deletions src/spesh/candidate.c
Expand Up @@ -97,6 +97,7 @@ void MVM_spesh_candidate_add(MVMThreadContext *tc, MVMSpeshPlanned *p) {
candidate->num_deopts = sg->num_deopt_addrs;
candidate->deopts = sg->deopt_addrs;
candidate->deopt_named_used_bit_field = sg->deopt_named_used_bit_field;
candidate->deopt_pea = sg->deopt_pea;
candidate->num_locals = sg->num_locals;
candidate->num_lexicals = sg->num_lexicals;
candidate->num_inlines = sg->num_inlines;
Expand Down Expand Up @@ -204,6 +205,7 @@ void MVM_spesh_candidate_destroy(MVMThreadContext *tc, MVMSpeshCandidate *candid
MVM_free(candidate->handlers);
MVM_free(candidate->spesh_slots);
MVM_free(candidate->deopts);
MVM_spesh_pea_destroy_deopt_info(tc, &(candidate->deopt_pea));
MVM_free(candidate->inlines);
MVM_free(candidate->local_types);
MVM_free(candidate->lexical_types);
Expand Down
3 changes: 3 additions & 0 deletions src/spesh/candidate.h
Expand Up @@ -28,6 +28,9 @@ struct MVMSpeshCandidate {
* typically don't update the array in specialized code. */
MVMuint64 deopt_named_used_bit_field;

/* Deopt information produced by escape analysis and scalar replacement. */
MVMSpeshPEADeopt deopt_pea;

/* Number of inlines and inlines table; see graph.h for description of
* the table format. */
MVMint32 num_inlines;
Expand Down
26 changes: 22 additions & 4 deletions src/spesh/deopt.c
Expand Up @@ -157,11 +157,30 @@ static void deopt_named_args_used(MVMThreadContext *tc, MVMFrame *f) {
f->params.named_used.bit_field = f->spesh_cand->deopt_named_used_bit_field;
}

/* Materialize an individual replaced object. */
static void materialize_object(MVMThreadContext *tc, MVMFrame *f, MVMuint32 info_idx) {
MVM_panic(1, "Deopt: materialize_object NYI");
}

/* Materialize all replaced objects that need to be at this deopt point. */
static void materialize_replaced_objects(MVMThreadContext *tc, MVMFrame *f, MVMint32 deopt_offset) {
MVMint32 i;
MVMSpeshCandidate *cand = f->spesh_cand;
for (i = 0; i < MVM_VECTOR_ELEMS(cand->deopt_pea.deopt_point); i++) {
if (cand->deopt_pea.deopt_point[i].deopt_point_idx == deopt_offset)
materialize_object(tc, f, cand->deopt_pea.deopt_point[i].materialize_info_idx);
}
}

static void deopt_frame(MVMThreadContext *tc, MVMFrame *f, MVMint32 deopt_offset, MVMint32 deopt_target) {
/* Found it; are we in an inline? */
MVMSpeshInline *inlines = f->spesh_cand->inlines;
/* Found it. We materialize any replaced objects first, then if
* we have stuff replaced in inlines then uninlining will take
* care of moving it out into the frames where it belongs. */
deopt_named_args_used(tc, f);
if (inlines) {
materialize_replaced_objects(tc, f, deopt_offset);

/* Check if we have inlines. */
if (f->spesh_cand->inlines) {
/* Yes, going to have to re-create the frames; uninline
* moves the interpreter, so we can just tweak the last
* frame. For the moment, uninlining creates its frames
Expand Down Expand Up @@ -192,7 +211,6 @@ static void deopt_frame(MVMThreadContext *tc, MVMFrame *f, MVMint32 deopt_offset
MVM_string_utf8_encode_C_string(tc, tc->cur_frame->static_info->body.cuuid));
#endif
}

}

/* De-optimizes the currently executing frame, provided it is specialized and
Expand Down
3 changes: 3 additions & 0 deletions src/spesh/graph.h
Expand Up @@ -69,6 +69,9 @@ struct MVMSpeshGraph {
MVMuint32 *always_retained_deopt_idxs;
MVMuint32 num_always_retained_deopt_idxs;

/* Deopt information produced by escape analysis and scalar replacement. */
MVMSpeshPEADeopt deopt_pea;

/* Table of information about inlines, laid out in order of nesting
* depth. Thus, going through the table in order and finding when we
* are within the bounds will show up each call frame that needs to
Expand Down
6 changes: 6 additions & 0 deletions src/spesh/pea.c
Expand Up @@ -545,3 +545,9 @@ void MVM_spesh_pea(MVMThreadContext *tc, MVMSpeshGraph *g) {
MVM_VECTOR_DESTROY(gs.bb_states[i].transformations);
MVM_VECTOR_DESTROY(gs.shadow_facts);
}

/* Clean up any deopt info. */
void MVM_spesh_pea_destroy_deopt_info(MVMThreadContext *tc, MVMSpeshPEADeopt *deopt_pea) {
MVM_VECTOR_DESTROY(deopt_pea->materialize_info);
MVM_VECTOR_DESTROY(deopt_pea->deopt_point);
}
38 changes: 38 additions & 0 deletions src/spesh/pea.h
Expand Up @@ -30,4 +30,42 @@ struct MVMSpeshPEAInfo {
MVMSpeshPEAAllocation *depend_allocation;
};

/* Information that we retain about a replaced allocations in order that we
* can materialize them upon deoptimization. */
struct MVMSpeshPEADeopt {
/* Array of materialization info, specifying how to materialize a given
* replaced object. */
MVM_VECTOR_DECL(MVMSpeshPEAMaterializeInfo, materialize_info);

/* Pairings of deoptimization points and objects to materialize at those
* point. */
MVM_VECTOR_DECL(MVMSpeshPEADeoptPoint, deopt_point);
};

/* The information needed to materialize a particular replaced allocation
* (that is, to recreate it on the heap). */
struct MVMSpeshPEAMaterializeInfo {
/* The spesh slot containing the STable of the object to materialize. */
MVMuint16 stable_sslot;

/* The register to materialize into. */
MVMuint16 target_reg;

/* A list of the registers holding the attributes to put into the
* materialized object. */
MVMuint16 *attr_regs;
};

/* Information about that needs to be materialized at a particular deopt
* point. */
struct MVMSpeshPEADeoptPoint {
/* The index of the deopt point. */
MVMint32 deopt_point_idx;

/* The index into the materialize_info specifying how to materialize
* this object. */
MVMuint32 materialize_info_idx;
};

void MVM_spesh_pea(MVMThreadContext *tc, MVMSpeshGraph *g);
void MVM_spesh_pea_destroy_deopt_info(MVMThreadContext *tc, MVMSpeshPEADeopt *deopt_pea);
3 changes: 3 additions & 0 deletions src/types.h
Expand Up @@ -203,6 +203,9 @@ typedef struct MVMSpeshDeoptUseEntry MVMSpeshDeoptUseEntry;
typedef struct MVMSpeshFrameWalker MVMSpeshFrameWalker;
typedef struct MVMSpeshPEAInfo MVMSpeshPEAInfo;
typedef struct MVMSpeshPEAAllocation MVMSpeshPEAAllocation;
typedef struct MVMSpeshPEADeopt MVMSpeshPEADeopt;
typedef struct MVMSpeshPEAMaterializeInfo MVMSpeshPEAMaterializeInfo;
typedef struct MVMSpeshPEADeoptPoint MVMSpeshPEADeoptPoint;
typedef struct MVMSTable MVMSTable;
typedef struct MVMStaticFrame MVMStaticFrame;
typedef struct MVMStaticFrameBody MVMStaticFrameBody;
Expand Down

0 comments on commit 913504d

Please sign in to comment.