6943304: remove tagged stack interpreter

Reviewed-by: coleenp, never, gbenson
This commit is contained in:
Christian Thalinger 2010-04-30 08:37:24 -07:00
parent 55457c9cc7
commit 0211f9703a
51 changed files with 510 additions and 1891 deletions

View file

@ -2867,12 +2867,6 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
}
#endif // _LP64
// MethodHandles code does not support TaggedStackInterpreter.
if (EnableMethodHandles && TaggedStackInterpreter) {
warning("TaggedStackInterpreter is not supported by MethodHandles code. Disabling TaggedStackInterpreter.");
TaggedStackInterpreter = false;
}
// Check the GC selections again.
if (!check_gc_consistency()) {
return JNI_EINVAL;
@ -2915,11 +2909,6 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedOops, false));
#endif // CC_INTERP
#ifdef ZERO
// Clear flags not supported by Zero
FLAG_SET_DEFAULT(TaggedStackInterpreter, false);
#endif // ZERO
#ifdef COMPILER2
if (!UseBiasedLocking || EmitSync != 0) {
UseOptoBiasInlining = false;

View file

@ -468,42 +468,16 @@ intptr_t* frame::interpreter_frame_local_at(int index) const {
return &((*interpreter_frame_locals_addr())[n]);
}
frame::Tag frame::interpreter_frame_local_tag(int index) const {
const int n = Interpreter::local_tag_offset_in_bytes(index)/wordSize;
return (Tag)(*interpreter_frame_locals_addr()) [n];
}
void frame::interpreter_frame_set_local_tag(int index, Tag tag) const {
const int n = Interpreter::local_tag_offset_in_bytes(index)/wordSize;
(*interpreter_frame_locals_addr())[n] = (intptr_t)tag;
}
intptr_t* frame::interpreter_frame_expression_stack_at(jint offset) const {
const int i = offset * interpreter_frame_expression_stack_direction();
const int n = ((i * Interpreter::stackElementSize()) +
Interpreter::value_offset_in_bytes())/wordSize;
const int n = i * Interpreter::stackElementWords;
return &(interpreter_frame_expression_stack()[n]);
}
frame::Tag frame::interpreter_frame_expression_stack_tag(jint offset) const {
const int i = offset * interpreter_frame_expression_stack_direction();
const int n = ((i * Interpreter::stackElementSize()) +
Interpreter::tag_offset_in_bytes())/wordSize;
return (Tag)(interpreter_frame_expression_stack()[n]);
}
void frame::interpreter_frame_set_expression_stack_tag(jint offset,
Tag tag) const {
const int i = offset * interpreter_frame_expression_stack_direction();
const int n = ((i * Interpreter::stackElementSize()) +
Interpreter::tag_offset_in_bytes())/wordSize;
interpreter_frame_expression_stack()[n] = (intptr_t)tag;
}
jint frame::interpreter_frame_expression_stack_size() const {
// Number of elements on the interpreter expression stack
// Callers should span by stackElementWords
int element_size = Interpreter::stackElementWords();
int element_size = Interpreter::stackElementWords;
if (frame::interpreter_frame_expression_stack_direction() < 0) {
return (interpreter_frame_expression_stack() -
interpreter_frame_tos_address() + 1)/element_size;
@ -585,20 +559,12 @@ void frame::interpreter_frame_print_on(outputStream* st) const {
for (i = 0; i < interpreter_frame_method()->max_locals(); i++ ) {
intptr_t x = *interpreter_frame_local_at(i);
st->print(" - local [" INTPTR_FORMAT "]", x);
if (TaggedStackInterpreter) {
Tag x = interpreter_frame_local_tag(i);
st->print(" - local tag [" INTPTR_FORMAT "]", x);
}
st->fill_to(23);
st->print_cr("; #%d", i);
}
for (i = interpreter_frame_expression_stack_size() - 1; i >= 0; --i ) {
intptr_t x = *interpreter_frame_expression_stack_at(i);
st->print(" - stack [" INTPTR_FORMAT "]", x);
if (TaggedStackInterpreter) {
Tag x = interpreter_frame_expression_stack_tag(i);
st->print(" - stack tag [" INTPTR_FORMAT "]", x);
}
st->fill_to(23);
st->print_cr("; #%d", i);
}
@ -950,103 +916,19 @@ void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool quer
}
}
if (TaggedStackInterpreter) {
// process locals & expression stack
InterpreterOopMap *mask = NULL;
#ifdef ASSERT
InterpreterOopMap oopmap_mask;
OopMapCache::compute_one_oop_map(m, bci, &oopmap_mask);
mask = &oopmap_mask;
#endif // ASSERT
oops_interpreted_locals_do(f, max_locals, mask);
oops_interpreted_expressions_do(f, signature, has_receiver,
m->max_stack(),
max_locals, mask);
InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f);
// process locals & expression stack
InterpreterOopMap mask;
if (query_oop_map_cache) {
m->mask_for(bci, &mask);
} else {
InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f);
// process locals & expression stack
InterpreterOopMap mask;
if (query_oop_map_cache) {
m->mask_for(bci, &mask);
} else {
OopMapCache::compute_one_oop_map(m, bci, &mask);
}
mask.iterate_oop(&blk);
OopMapCache::compute_one_oop_map(m, bci, &mask);
}
mask.iterate_oop(&blk);
}
void frame::oops_interpreted_locals_do(OopClosure *f,
int max_locals,
InterpreterOopMap *mask) {
// Process locals then interpreter expression stack
for (int i = 0; i < max_locals; i++ ) {
Tag tag = interpreter_frame_local_tag(i);
if (tag == TagReference) {
oop* addr = (oop*) interpreter_frame_local_at(i);
assert((intptr_t*)addr >= sp(), "must be inside the frame");
f->do_oop(addr);
#ifdef ASSERT
} else {
assert(tag == TagValue, "bad tag value for locals");
oop* p = (oop*) interpreter_frame_local_at(i);
// Not always true - too bad. May have dead oops without tags in locals.
// assert(*p == NULL || !(*p)->is_oop(), "oop not tagged on interpreter locals");
assert(*p == NULL || !mask->is_oop(i), "local oop map mismatch");
#endif // ASSERT
}
}
}
void frame::oops_interpreted_expressions_do(OopClosure *f,
symbolHandle signature,
bool has_receiver,
int max_stack,
int max_locals,
InterpreterOopMap *mask) {
// There is no stack no matter what the esp is pointing to (native methods
// might look like expression stack is nonempty).
if (max_stack == 0) return;
// Point the top of the expression stack above arguments to a call so
// arguments aren't gc'ed as both stack values for callee and callee
// arguments in callee's locals.
int args_size = 0;
if (!signature.is_null()) {
args_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
}
intptr_t *tos_addr = interpreter_frame_tos_at(args_size);
assert(args_size != 0 || tos_addr == interpreter_frame_tos_address(), "these are same");
intptr_t *frst_expr = interpreter_frame_expression_stack_at(0);
// In case of exceptions, the expression stack is invalid and the esp
// will be reset to express this condition. Therefore, we call f only
// if addr is 'inside' the stack (i.e., addr >= esp for Intel).
bool in_stack;
if (interpreter_frame_expression_stack_direction() > 0) {
in_stack = (intptr_t*)frst_expr <= tos_addr;
} else {
in_stack = (intptr_t*)frst_expr >= tos_addr;
}
if (!in_stack) return;
jint stack_size = interpreter_frame_expression_stack_size() - args_size;
for (int j = 0; j < stack_size; j++) {
Tag tag = interpreter_frame_expression_stack_tag(j);
if (tag == TagReference) {
oop *addr = (oop*) interpreter_frame_expression_stack_at(j);
f->do_oop(addr);
#ifdef ASSERT
} else {
assert(tag == TagValue, "bad tag value for stack element");
oop *p = (oop*) interpreter_frame_expression_stack_at((j));
assert(*p == NULL || !mask->is_oop(j+max_locals), "stack oop map mismatch");
#endif // ASSERT
}
}
}
void frame::oops_interpreted_arguments_do(symbolHandle signature, bool has_receiver, OopClosure* f) {
InterpretedArgumentOopFinder finder(signature, has_receiver, this, f);
finder.oops_do();
@ -1306,29 +1188,18 @@ void frame::zap_dead_interpreted_locals(JavaThread *thread, const RegisterMap* m
int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
if (TaggedStackInterpreter) {
InterpreterOopMap *mask = NULL;
#ifdef ASSERT
InterpreterOopMap oopmap_mask;
methodHandle method(thread, m);
OopMapCache::compute_one_oop_map(method, bci, &oopmap_mask);
mask = &oopmap_mask;
#endif // ASSERT
oops_interpreted_locals_do(&_check_oop, max_locals, mask);
} else {
// process dynamic part
InterpreterFrameClosure value_blk(this, max_locals, m->max_stack(),
&_check_value);
InterpreterFrameClosure oop_blk(this, max_locals, m->max_stack(),
&_check_oop );
InterpreterFrameClosure dead_blk(this, max_locals, m->max_stack(),
&_zap_dead );
// process dynamic part
InterpreterFrameClosure value_blk(this, max_locals, m->max_stack(),
&_check_value);
InterpreterFrameClosure oop_blk(this, max_locals, m->max_stack(),
&_check_oop );
InterpreterFrameClosure dead_blk(this, max_locals, m->max_stack(),
&_zap_dead );
// get frame map
InterpreterOopMap mask;
m->mask_for(bci, &mask);
mask.iterate_all( &oop_blk, &value_blk, &dead_blk);
}
// get frame map
InterpreterOopMap mask;
m->mask_for(bci, &mask);
mask.iterate_all( &oop_blk, &value_blk, &dead_blk);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -191,26 +191,10 @@ class frame VALUE_OBJ_CLASS_SPEC {
intptr_t* interpreter_frame_mdx_addr() const;
public:
// Tags for TaggedStackInterpreter
enum Tag {
TagValue = 0, // Important: must be zero to use G0 on sparc.
TagReference = 0x555, // Reference type - is an oop that needs gc.
TagCategory2 = 0x666 // Only used internally by interpreter
// and not written to the java stack.
// The values above are chosen so that misuse causes a crash
// with a recognizable value.
};
static Tag tag_for_basic_type(BasicType typ) {
return (typ == T_OBJECT ? TagReference : TagValue);
}
// Locals
// The _at version returns a pointer because the address is used for GC.
intptr_t* interpreter_frame_local_at(int index) const;
Tag interpreter_frame_local_tag(int index) const;
void interpreter_frame_set_local_tag(int index, Tag tag) const;
void interpreter_frame_set_locals(intptr_t* locs);
@ -260,8 +244,6 @@ class frame VALUE_OBJ_CLASS_SPEC {
// The _at version returns a pointer because the address is used for GC.
intptr_t* interpreter_frame_expression_stack_at(jint offset) const;
Tag interpreter_frame_expression_stack_tag(jint offset) const;
void interpreter_frame_set_expression_stack_tag(jint offset, Tag tag) const;
// top of expression stack
intptr_t* interpreter_frame_tos_at(jint offset) const;
@ -375,12 +357,6 @@ class frame VALUE_OBJ_CLASS_SPEC {
void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true);
private:
void oops_interpreted_locals_do(OopClosure *f,
int max_locals,
InterpreterOopMap *mask);
void oops_interpreted_expressions_do(OopClosure *f, symbolHandle signature,
bool has_receiver, int max_stack, int max_locals,
InterpreterOopMap *mask);
void oops_interpreted_arguments_do(symbolHandle signature, bool has_receiver, OopClosure* f);
// Iteration of oops

View file

@ -1,5 +1,5 @@
/*
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -3497,9 +3497,6 @@ class CommandLineFlags {
develop(bool, TraceInvokeDynamic, false, \
"trace internal invoke dynamic operations") \
\
product(bool, TaggedStackInterpreter, false, \
"Insert tags in interpreter execution stack for oopmap generaion")\
\
diagnostic(bool, PauseAtStartup, false, \
"Causes the VM to pause at startup time and wait for the pause " \
"file to be removed (default: ./vm.paused.<pid>)") \

View file

@ -1,5 +1,5 @@
/*
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -417,17 +417,9 @@ intptr_t* JavaCallArguments::parameters() {
// Handle conversion
_value[i] = (intptr_t)Handle::raw_resolve((oop *)_value[i]);
}
// The parameters are moved to the parameters array to include the tags.
if (TaggedStackInterpreter) {
// Tags are interspersed with arguments. Tags are first.
int tagged_index = i*2;
_parameters[tagged_index] = _is_oop[i] ? frame::TagReference :
frame::TagValue;
_parameters[tagged_index+1] = _value[i];
}
}
// Return argument vector
return TaggedStackInterpreter ? _parameters : _value;
return _value;
}

View file

@ -66,11 +66,9 @@ class JavaCallArguments : public StackObj {
};
intptr_t _value_buffer [_default_size + 1];
intptr_t _parameter_buffer [_default_size*2 + 1];
bool _is_oop_buffer[_default_size + 1];
intptr_t* _value;
intptr_t* _parameters;
bool* _is_oop;
int _size;
int _max_size;
@ -81,7 +79,6 @@ class JavaCallArguments : public StackObj {
_value = &_value_buffer[1];
_is_oop = &_is_oop_buffer[1];
_parameters = &_parameter_buffer[0];
_max_size = _default_size;
_size = 0;
_start_at_zero = false;
@ -99,11 +96,10 @@ class JavaCallArguments : public StackObj {
if (max_size > _default_size) {
_value = NEW_RESOURCE_ARRAY(intptr_t, max_size + 1);
_is_oop = NEW_RESOURCE_ARRAY(bool, max_size + 1);
if (TaggedStackInterpreter) {
_parameters = NEW_RESOURCE_ARRAY(intptr_t, max_size*2 + 1);
}
// Reserve room for potential receiver in value and is_oop
_value++; _is_oop++;
_max_size = max_size;
_size = 0;
_start_at_zero = false;

View file

@ -1842,14 +1842,11 @@ class AdapterFingerPrint : public CHeapObj {
case T_OBJECT:
case T_ARRAY:
if (!TaggedStackInterpreter) {
#ifdef _LP64
return T_LONG;
return T_LONG;
#else
return T_INT;
return T_INT;
#endif
}
return T_OBJECT;
case T_INT:
case T_LONG:
@ -2595,17 +2592,9 @@ JRT_LEAF(intptr_t*, SharedRuntime::OSR_migration_begin( JavaThread *thread) )
// Copy the locals. Order is preserved so that loading of longs works.
// Since there's no GC I can copy the oops blindly.
assert( sizeof(HeapWord)==sizeof(intptr_t), "fix this code");
if (TaggedStackInterpreter) {
for (int i = 0; i < max_locals; i++) {
// copy only each local separately to the buffer avoiding the tag
buf[i] = *fr.interpreter_frame_local_at(max_locals-i-1);
}
} else {
Copy::disjoint_words(
(HeapWord*)fr.interpreter_frame_local_at(max_locals-1),
Copy::disjoint_words((HeapWord*)fr.interpreter_frame_local_at(max_locals-1),
(HeapWord*)&buf[0],
max_locals);
}
// Inflate locks. Copy the displaced headers. Be careful, there can be holes.
int i = max_locals;

View file

@ -244,51 +244,30 @@ StackValueCollection* interpretedVFrame::locals() const {
StackValueCollection* result = new StackValueCollection(length);
// Get oopmap describing oops and int for current bci
if (TaggedStackInterpreter) {
for(int i=0; i < length; i++) {
// Find stack location
intptr_t *addr = locals_addr_at(i);
// Depending on oop/int put it in the right package
StackValue *sv;
frame::Tag tag = fr().interpreter_frame_local_tag(i);
if (tag == frame::TagReference) {
// oop value
Handle h(*(oop *)addr);
sv = new StackValue(h);
} else {
// integer
sv = new StackValue(*addr);
}
assert(sv != NULL, "sanity check");
result->add(sv);
}
InterpreterOopMap oop_mask;
if (TraceDeoptimization && Verbose) {
methodHandle m_h(thread(), method());
OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
} else {
InterpreterOopMap oop_mask;
if (TraceDeoptimization && Verbose) {
methodHandle m_h(thread(), method());
OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
} else {
method()->mask_for(bci(), &oop_mask);
}
// handle locals
for(int i=0; i < length; i++) {
// Find stack location
intptr_t *addr = locals_addr_at(i);
method()->mask_for(bci(), &oop_mask);
}
// handle locals
for(int i=0; i < length; i++) {
// Find stack location
intptr_t *addr = locals_addr_at(i);
// Depending on oop/int put it in the right package
StackValue *sv;
if (oop_mask.is_oop(i)) {
// oop value
Handle h(*(oop *)addr);
sv = new StackValue(h);
} else {
// integer
sv = new StackValue(*addr);
}
assert(sv != NULL, "sanity check");
result->add(sv);
// Depending on oop/int put it in the right package
StackValue *sv;
if (oop_mask.is_oop(i)) {
// oop value
Handle h(*(oop *)addr);
sv = new StackValue(h);
} else {
// integer
sv = new StackValue(*addr);
}
assert(sv != NULL, "sanity check");
result->add(sv);
}
return result;
}
@ -331,53 +310,31 @@ StackValueCollection* interpretedVFrame::expressions() const {
int nof_locals = method()->max_locals();
StackValueCollection* result = new StackValueCollection(length);
if (TaggedStackInterpreter) {
// handle expressions
for(int i=0; i < length; i++) {
// Find stack location
intptr_t *addr = fr().interpreter_frame_expression_stack_at(i);
frame::Tag tag = fr().interpreter_frame_expression_stack_tag(i);
// Depending on oop/int put it in the right package
StackValue *sv;
if (tag == frame::TagReference) {
// oop value
Handle h(*(oop *)addr);
sv = new StackValue(h);
} else {
// otherwise
sv = new StackValue(*addr);
}
assert(sv != NULL, "sanity check");
result->add(sv);
}
InterpreterOopMap oop_mask;
// Get oopmap describing oops and int for current bci
if (TraceDeoptimization && Verbose) {
methodHandle m_h(method());
OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
} else {
InterpreterOopMap oop_mask;
// Get oopmap describing oops and int for current bci
if (TraceDeoptimization && Verbose) {
methodHandle m_h(method());
OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
} else {
method()->mask_for(bci(), &oop_mask);
}
// handle expressions
for(int i=0; i < length; i++) {
// Find stack location
intptr_t *addr = fr().interpreter_frame_expression_stack_at(i);
method()->mask_for(bci(), &oop_mask);
}
// handle expressions
for(int i=0; i < length; i++) {
// Find stack location
intptr_t *addr = fr().interpreter_frame_expression_stack_at(i);
// Depending on oop/int put it in the right package
StackValue *sv;
if (oop_mask.is_oop(i + nof_locals)) {
// oop value
Handle h(*(oop *)addr);
sv = new StackValue(h);
} else {
// integer
sv = new StackValue(*addr);
}
assert(sv != NULL, "sanity check");
result->add(sv);
// Depending on oop/int put it in the right package
StackValue *sv;
if (oop_mask.is_oop(i + nof_locals)) {
// oop value
Handle h(*(oop *)addr);
sv = new StackValue(h);
} else {
// integer
sv = new StackValue(*addr);
}
assert(sv != NULL, "sanity check");
result->add(sv);
}
return result;
}

View file

@ -309,11 +309,6 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters,
default:
ShouldNotReachHere();
}
if (TaggedStackInterpreter) {
// Write tag to the stack
iframe()->interpreter_frame_set_expression_stack_tag(i,
frame::tag_for_basic_type(value->type()));
}
}
@ -335,11 +330,6 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters,
default:
ShouldNotReachHere();
}
if (TaggedStackInterpreter) {
// Write tag to stack
iframe()->interpreter_frame_set_local_tag(i,
frame::tag_for_basic_type(value->type()));
}
}
if (is_top_frame && JvmtiExport::can_pop_frame() && thread->popframe_forcing_deopt_reexecution()) {
@ -354,9 +344,8 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters,
void* saved_args = thread->popframe_preserved_args();
assert(saved_args != NULL, "must have been saved by interpreter");
#ifdef ASSERT
int stack_words = Interpreter::stackElementWords();
assert(popframe_preserved_args_size_in_words <=
iframe()->interpreter_frame_expression_stack_size()*stack_words,
iframe()->interpreter_frame_expression_stack_size()*Interpreter::stackElementWords,
"expression stack size should have been extended");
#endif // ASSERT
int top_element = iframe()->interpreter_frame_expression_stack_size()-1;