if (sd == NULL) return ErrorCodes::vmString_prim_error(SLOTNAMEERROR); if (sd->is_obj_slot() && name->is_1arg_keyword()) return Memory->assignmentMirrorObj; abstract_vframe* vf = vfo->as_vframe(); oop contents = vf->get_slot(sd); return contents->as_mirror(); } # define VFRAME_PRIM(name, what) \ oop vframeMap::name(oop obj) { \ TEST; \ abstract_vframe* vf = vfo->as_vframe(); \ return what; \ } \ VFRAME_PRIM(mirror_bci, as_smiOop(vf->bci())) VFRAME_PRIM(mirror_methodHolder, vf->methodHolder_object()->as_mirror()) oop vframeMap::mirror_receiver(oop obj) { TEST; return vfo->as_vframe()->receiver()->as_mirror(); } oop vframeMap::mirror_parent(oop obj) { TEST; abstract_vframe* parent = vfo->as_vframe()->parent(); if (!parent) return ErrorCodes::vmString_prim_error(NOPARENTERROR); assert(vfo->process() == vmProcess || !parent->is_first_self_vframe(), "doIt of a process cannot have blocks!"); vframeOop nvfo = new_vframeOop(vfo->process(), parent); return nvfo->as_mirror();
void set_index(int i) { STORE_OOP(&addr()->_index, as_smiOop(i)); }
Node* NodeGen::perform(SCodeScope* sc, LookupType l, PReg* self, fint argc, oop del, oop mh, MergeNode* nlrPoint, PRegBList* exprStack, SplitSig* sig) { return selfCall(sc, l, self, as_smiOop(argc), del, mh, nlrPoint, argc, exprStack, sig); }
void MethodIterator::dispatch(MethodClosure* blk) { bool oldFailState = blk->in_prim_failure_block(); blk->set_prim_failure(_interval->in_prim_failure_block()); CodeIterator iter(_interval->method(), _interval->begin_bci()); int lastArgNo = _interval->method()->number_of_arguments() - 1; blk->set_method(_interval->method()); int next_bci = _interval->begin_bci(); while (next_bci < _interval->end_bci() && !blk->aborting()) { iter.set_bci(next_bci); blk->set_bci(iter.bci()); next_bci = iter.next_bci(); blk->set_next_bci(next_bci); switch(iter.code()) { case Bytecodes::push_temp_0: blk->push_temporary(0); break; case Bytecodes::push_temp_1: blk->push_temporary(1); break; case Bytecodes::push_temp_2: blk->push_temporary(2); break; case Bytecodes::push_temp_3: blk->push_temporary(3); break; case Bytecodes::push_temp_4: blk->push_temporary(4); break; case Bytecodes::push_temp_5: blk->push_temporary(5); break; case Bytecodes::unimplemented_06: unknown_code(Bytecodes::unimplemented_06); break; case Bytecodes::push_temp_n: blk->push_temporary(255 - iter.byte_at(1)); break; case Bytecodes::push_arg_1: blk->push_argument(lastArgNo); break; case Bytecodes::push_arg_2: blk->push_argument(lastArgNo - 1); break; case Bytecodes::push_arg_3: blk->push_argument(lastArgNo - 2); break; case Bytecodes::push_arg_n: blk->push_argument(lastArgNo - iter.byte_at(1)); break; case Bytecodes::allocate_temp_1: blk->allocate_temporaries(1); break; case Bytecodes::allocate_temp_2: blk->allocate_temporaries(2); break; case Bytecodes::allocate_temp_3: blk->allocate_temporaries(3); break; case Bytecodes::allocate_temp_n: blk->allocate_temporaries(map0to256(iter.byte_at(1))); break; case Bytecodes::store_temp_0_pop: blk->store_temporary(0); blk->pop(); break; case Bytecodes::store_temp_1_pop: blk->store_temporary(1); blk->pop(); break; case Bytecodes::store_temp_2_pop: blk->store_temporary(2); blk->pop(); break; case Bytecodes::store_temp_3_pop: blk->store_temporary(3); blk->pop(); break; case Bytecodes::store_temp_4_pop: blk->store_temporary(4); blk->pop(); break; case Bytecodes::store_temp_5_pop: blk->store_temporary(5); blk->pop(); break; case Bytecodes::store_temp_n: blk->store_temporary(255 - iter.byte_at(1)); break; case Bytecodes::store_temp_n_pop: blk->store_temporary(255 - iter.byte_at(1)); blk->pop(); break; case Bytecodes::push_neg_n: blk->push_literal(as_smiOop(-(int) iter.byte_at(1))); break; case Bytecodes::push_succ_n: blk->push_literal(as_smiOop(iter.byte_at(1)+1)); break; case Bytecodes::push_literal: blk->push_literal(iter.oop_at(1)); break; case Bytecodes::push_tos: blk->push_tos(); break; case Bytecodes::push_self: blk->push_self(); break; case Bytecodes::push_nil: blk->push_literal(nilObj); break; case Bytecodes::push_true: blk->push_literal(trueObj); break; case Bytecodes::push_false: blk->push_literal(falseObj); break; case Bytecodes::unimplemented_20: unknown_code(Bytecodes::unimplemented_20); break; case Bytecodes::unimplemented_21: unknown_code(Bytecodes::unimplemented_21); break; case Bytecodes::unimplemented_22: unknown_code(Bytecodes::unimplemented_22); break; case Bytecodes::unimplemented_23: unknown_code(Bytecodes::unimplemented_23); break; case Bytecodes::unimplemented_24: unknown_code(Bytecodes::unimplemented_24); break; case Bytecodes::unimplemented_25: unknown_code(Bytecodes::unimplemented_25); break; case Bytecodes::unimplemented_26: unknown_code(Bytecodes::unimplemented_26); break; case Bytecodes::unimplemented_27: unknown_code(Bytecodes::unimplemented_27); break; case Bytecodes::return_instVar_name: { symbolOop name = symbolOop(iter.oop_at(1)); assert(name->is_symbol(), "must be symbol"); blk->push_instVar_name(name); blk->method_return(0); } break; case Bytecodes::push_classVar: { associationOop assoc = associationOop(iter.oop_at(1)); assert(assoc->is_association(), "must be association"); blk->push_classVar(assoc); } break; case Bytecodes::store_classVar_pop: { associationOop assoc = associationOop(iter.oop_at(1)); assert(assoc->is_association(), "must be association"); blk->store_classVar(assoc); blk->pop(); } break; case Bytecodes::store_classVar: { associationOop assoc = associationOop(iter.oop_at(1)); assert(assoc->is_association(), "must be association"); blk->store_classVar(assoc); } break; case Bytecodes::return_instVar: { smiOop offset = smiOop(iter.oop_at(1)); assert(offset->is_smi(), "must be smi"); blk->push_instVar(offset->value()); blk->method_return(0); } break; case Bytecodes::push_instVar: { smiOop offset = smiOop(iter.oop_at(1)); assert(offset->is_smi(), "must be smi"); blk->push_instVar(offset->value()); } break; case Bytecodes::store_instVar_pop: { smiOop offset = smiOop(iter.oop_at(1)); assert(offset->is_smi(), "must be smi"); blk->store_instVar(offset->value()); blk->pop(); } break; case Bytecodes::store_instVar:{ smiOop offset = smiOop(iter.oop_at(1)); assert(offset->is_smi(), "must be smi"); blk->store_instVar(offset->value()); } break; case Bytecodes::float_allocate: blk->allocate_temporaries(1 + iter.byte_at(1)*2); blk->float_allocate(iter.byte_at(2), iter.byte_at(3)); break; case Bytecodes::float_floatify_pop: blk->float_floatify(Floats::floatify, blk->float_at(iter.byte_at(1))); break; case Bytecodes::float_move: blk->float_move(blk->float_at(iter.byte_at(1)), blk->float_at(iter.byte_at(2))); break; case Bytecodes::float_set: blk->float_set(blk->float_at(iter.byte_at(1)), *(doubleOop*)iter.aligned_oop(2)); break; case Bytecodes::float_nullary_op: blk->float_nullary(Floats::Function(iter.byte_at(2)), blk->float_at(iter.byte_at(1))); break; case Bytecodes::float_unary_op: blk->float_unary(Floats::Function(iter.byte_at(2)), blk->float_at(iter.byte_at(1))); break; case Bytecodes::float_binary_op: blk->float_binary(Floats::Function(iter.byte_at(2)), blk->float_at(iter.byte_at(1))); break; case Bytecodes::float_unary_op_to_oop: blk->float_unaryToOop(Floats::Function(iter.byte_at(2)), blk->float_at(iter.byte_at(1))); break; case Bytecodes::float_binary_op_to_oop: blk->float_binaryToOop(Floats::Function(iter.byte_at(2)), blk->float_at(iter.byte_at(1))); break; case Bytecodes::unimplemented_39: unknown_code(Bytecodes::unimplemented_39); break; case Bytecodes::unimplemented_3a: unknown_code(Bytecodes::unimplemented_3a); break; case Bytecodes::unimplemented_3b: unknown_code(Bytecodes::unimplemented_3b); break; case Bytecodes::unimplemented_3c: unknown_code(Bytecodes::unimplemented_3c); break; case Bytecodes::push_instVar_name: { symbolOop name = symbolOop(iter.oop_at(1)); assert(name->is_symbol(), "must be symbol"); blk->push_instVar_name(name); } break; case Bytecodes::store_instVar_pop_name: { symbolOop name = symbolOop(iter.oop_at(1)); assert(name->is_symbol(), "must be symbol"); blk->store_instVar_name(name); blk->pop(); } break; case Bytecodes::store_instVar_name: { symbolOop name = symbolOop(iter.oop_at(1)); assert(name->is_symbol(), "must be symbol"); blk->store_instVar_name(name); } break; case Bytecodes::push_temp_0_context_0: blk->push_temporary(0, 0); break; case Bytecodes::push_temp_1_context_0: blk->push_temporary(1, 0); break; case Bytecodes::push_temp_2_context_0: blk->push_temporary(2, 0); break; case Bytecodes::push_temp_n_context_0: blk->push_temporary(iter.byte_at(1), 0); break; case Bytecodes::store_temp_0_context_0_pop: blk->store_temporary(0, 0); blk->pop(); break; case Bytecodes::store_temp_1_context_0_pop: blk->store_temporary(1, 0); blk->pop(); break; case Bytecodes::store_temp_2_context_0_pop: blk->store_temporary(2, 0); blk->pop(); break; case Bytecodes::store_temp_n_context_0_pop: blk->store_temporary(iter.byte_at(1), 0); blk->pop(); break; case Bytecodes::push_new_closure_context_0: blk->allocate_closure(context_as_scope, 0, methodOop(iter.oop_at(1))); break; case Bytecodes::push_new_closure_context_1: blk->allocate_closure(context_as_scope, 1, methodOop(iter.oop_at(1))); break; case Bytecodes::push_new_closure_context_2: blk->allocate_closure(context_as_scope, 2, methodOop(iter.oop_at(1))); break; case Bytecodes::push_new_closure_context_n: blk->allocate_closure(context_as_scope, iter.byte_at(1), methodOop(iter.oop_at(2))); break; case Bytecodes::install_new_context_method_0: blk->allocate_context(0, true); break; case Bytecodes::install_new_context_method_1: blk->allocate_context(1, true); break; case Bytecodes::install_new_context_method_2: blk->allocate_context(2, true); break; case Bytecodes::install_new_context_method_n: blk->allocate_context(iter.byte_at(1), true); break; case Bytecodes::push_temp_0_context_1: blk->push_temporary(0, 1); break; case Bytecodes::push_temp_1_context_1: blk->push_temporary(1, 1); break; case Bytecodes::push_temp_2_context_1: blk->push_temporary(2, 1); break; case Bytecodes::push_temp_n_context_1: blk->push_temporary(iter.byte_at(1), 1); break; case Bytecodes::store_temp_0_context_1_pop: blk->store_temporary(0, 1); blk->pop(); break; case Bytecodes::store_temp_1_context_1_pop: blk->store_temporary(1, 1); blk->pop(); break; case Bytecodes::store_temp_2_context_1_pop: blk->store_temporary(2, 1); blk->pop(); break; case Bytecodes::store_temp_n_context_1_pop: blk->store_temporary(iter.byte_at(1), 1); blk->pop(); break; case Bytecodes::push_new_closure_tos_0: blk->allocate_closure(tos_as_scope, 0, methodOop(iter.oop_at(1))); break; case Bytecodes::push_new_closure_tos_1: blk->allocate_closure(tos_as_scope, 1, methodOop(iter.oop_at(1))); break; case Bytecodes::push_new_closure_tos_2: blk->allocate_closure(tos_as_scope, 2, methodOop(iter.oop_at(1))); break; case Bytecodes::push_new_closure_tos_n: blk->allocate_closure(tos_as_scope, iter.byte_at(1), methodOop(iter.oop_at(2))); break; case Bytecodes::only_pop: blk->pop(); break; case Bytecodes::install_new_context_block_1: blk->allocate_context(1, false); break; case Bytecodes::install_new_context_block_2: blk->allocate_context(2, false); break; case Bytecodes::install_new_context_block_n: blk->allocate_context(iter.byte_at(1), false); break; case Bytecodes::push_temp_0_context_n: blk->push_temporary(0, iter.byte_at(1)); break; case Bytecodes::push_temp_1_context_n: blk->push_temporary(1, iter.byte_at(1)); break; case Bytecodes::push_temp_2_context_n: blk->push_temporary(2, iter.byte_at(1)); break; case Bytecodes::push_temp_n_context_n: blk->push_temporary(iter.byte_at(1), map0to256(iter.byte_at(2))); break; case Bytecodes::store_temp_0_context_n_pop: blk->store_temporary(0, iter.byte_at(1)); blk->pop(); break; case Bytecodes::store_temp_1_context_n_pop: blk->store_temporary(1, iter.byte_at(1)); blk->pop(); break; case Bytecodes::store_temp_2_context_n_pop: blk->store_temporary(2, iter.byte_at(1)); blk->pop(); break; case Bytecodes::store_temp_n_context_n_pop: blk->store_temporary(iter.byte_at(1), map0to256(iter.byte_at(2))); blk->pop(); break; case Bytecodes::set_self_via_context: blk->set_self_via_context(); break; case Bytecodes::copy_1_into_context: blk->copy_argument_into_context(lastArgNo - iter.byte_at(1), 0); break; case Bytecodes::copy_2_into_context: blk->copy_argument_into_context(lastArgNo - iter.byte_at(1), 0); blk->copy_argument_into_context(lastArgNo - iter.byte_at(2), 1); break; case Bytecodes::copy_n_into_context: { int len = map0to256(iter.byte_at(1)); for (int i = 0; i < len; i++) blk->copy_argument_into_context(lastArgNo - iter.byte_at(i + 2), i); break; } case Bytecodes::copy_self_into_context: blk->copy_self_into_context(); break; case Bytecodes::copy_self_1_into_context: blk->copy_self_into_context(); blk->copy_argument_into_context(lastArgNo - iter.byte_at(1), 1); break; case Bytecodes::copy_self_2_into_context: blk->copy_self_into_context(); blk->copy_argument_into_context(lastArgNo - iter.byte_at(1), 1); blk->copy_argument_into_context(lastArgNo - iter.byte_at(2), 2); break; case Bytecodes::copy_self_n_into_context: { blk->copy_self_into_context(); int len = map0to256(iter.byte_at(1)); for (int i = 0; i < len; i++) blk->copy_argument_into_context(lastArgNo - iter.byte_at(i + 2), i+1); break; } case Bytecodes::ifTrue_byte: { IfNode* node = MethodIterator::factory->new_IfNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), true, iter.byte_at(2), iter.byte_at(1)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->if_node(node); next_bci = node->end_bci(); break; } case Bytecodes::ifFalse_byte: { IfNode* node = MethodIterator::factory->new_IfNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), false, iter.byte_at(2), iter.byte_at(1)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->if_node(node); next_bci = node->end_bci(); break; } case Bytecodes::and_byte: { AndNode* node = MethodIterator::factory->new_AndNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), iter.byte_at(1)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->cond_node(node); next_bci = node->end_bci(); break; } case Bytecodes::or_byte: { OrNode* node = MethodIterator::factory->new_OrNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), iter.byte_at(1)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->cond_node(node); next_bci = node->end_bci(); break; } case Bytecodes::whileTrue_byte: // ignore since they are inside WhileNode expression body break; case Bytecodes::whileFalse_byte: // ignore since they are inside WhileNode expression body break; case Bytecodes::jump_else_byte: should_never_encounter(Bytecodes::jump_else_byte); break; case Bytecodes::jump_loop_byte: { WhileNode* node = MethodIterator::factory->new_WhileNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), iter.byte_at(2), iter.byte_at(1)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->while_node(node); next_bci = node->end_bci(); break; } case Bytecodes::ifTrue_word: { IfNode* node = MethodIterator::factory->new_IfNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), true, iter.word_at(2), iter.byte_at(1)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->if_node(node); next_bci = node->end_bci(); break; } case Bytecodes::ifFalse_word: { IfNode* node = MethodIterator::factory->new_IfNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), false, iter.word_at(2), iter.byte_at(1)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->if_node(node); next_bci = node->end_bci(); break; } case Bytecodes::and_word: { AndNode* node = MethodIterator::factory->new_AndNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), iter.word_at(1)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->cond_node(node); next_bci = node->end_bci(); break; } case Bytecodes::or_word: { OrNode* node = MethodIterator::factory->new_OrNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), iter.word_at(1)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->cond_node(node); next_bci = node->end_bci(); break; } case Bytecodes::whileTrue_word: // Ignore since they are inside WhileNode expression body break; case Bytecodes::whileFalse_word: // Ignore since they are inside WhileNode expression body break; case Bytecodes::jump_else_word: should_never_encounter(Bytecodes::jump_else_word); break; case Bytecodes::jump_loop_word: { WhileNode* node = MethodIterator::factory->new_WhileNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), iter.word_at(1 + oopSize), iter.word_at(1)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->while_node(node); next_bci = node->end_bci(); break; } case Bytecodes::interpreted_send_0: // fall through case Bytecodes::interpreted_send_1: // fall through case Bytecodes::interpreted_send_2: // fall through case Bytecodes::interpreted_send_n: // fall through case Bytecodes::compiled_send_0: // fall through case Bytecodes::compiled_send_1: // fall through case Bytecodes::compiled_send_2: // fall through case Bytecodes::compiled_send_n: // fall through case Bytecodes::primitive_send_0: // fall through case Bytecodes::primitive_send_1: // fall through case Bytecodes::primitive_send_2: // fall through case Bytecodes::primitive_send_n: // fall through case Bytecodes::polymorphic_send_0: // fall through case Bytecodes::polymorphic_send_1: // fall through case Bytecodes::polymorphic_send_2: // fall through case Bytecodes::polymorphic_send_n: // fall through case Bytecodes::megamorphic_send_0: // fall through case Bytecodes::megamorphic_send_1: // fall through case Bytecodes::megamorphic_send_2: // fall through case Bytecodes::megamorphic_send_n: // fall through blk->normal_send(iter.ic()); break; case Bytecodes::interpreted_send_0_pop: // fall through case Bytecodes::interpreted_send_1_pop: // fall through case Bytecodes::interpreted_send_2_pop: // fall through case Bytecodes::interpreted_send_n_pop: // fall through case Bytecodes::compiled_send_0_pop: // fall through case Bytecodes::compiled_send_1_pop: // fall through case Bytecodes::compiled_send_2_pop: // fall through case Bytecodes::compiled_send_n_pop: // fall through case Bytecodes::primitive_send_0_pop: // fall through case Bytecodes::primitive_send_1_pop: // fall through case Bytecodes::primitive_send_2_pop: // fall through case Bytecodes::primitive_send_n_pop: // fall through case Bytecodes::polymorphic_send_0_pop: // fall through case Bytecodes::polymorphic_send_1_pop: // fall through case Bytecodes::polymorphic_send_2_pop: // fall through case Bytecodes::polymorphic_send_n_pop: // fall through case Bytecodes::megamorphic_send_0_pop: // fall through case Bytecodes::megamorphic_send_1_pop: // fall through case Bytecodes::megamorphic_send_2_pop: // fall through case Bytecodes::megamorphic_send_n_pop: // fall through blk->normal_send(iter.ic()); blk->pop(); break; case Bytecodes::interpreted_send_self: // fall through case Bytecodes::compiled_send_self: // fall through case Bytecodes::primitive_send_self: // fall through case Bytecodes::polymorphic_send_self: // fall through case Bytecodes::megamorphic_send_self: // fall through blk->self_send(iter.ic()); break; case Bytecodes::interpreted_send_self_pop: // fall through case Bytecodes::compiled_send_self_pop: // fall through case Bytecodes::primitive_send_self_pop: // fall through case Bytecodes::polymorphic_send_self_pop: // fall through case Bytecodes::megamorphic_send_self_pop: // fall through blk->self_send(iter.ic()); blk->pop(); break; case Bytecodes::interpreted_send_super: // fall through case Bytecodes::compiled_send_super: // fall through case Bytecodes::primitive_send_super: // fall through case Bytecodes::polymorphic_send_super: // fall through case Bytecodes::megamorphic_send_super: // fall through blk->super_send(iter.ic()); break; case Bytecodes::interpreted_send_super_pop: // fall through case Bytecodes::compiled_send_super_pop: // fall through case Bytecodes::primitive_send_super_pop: // fall through case Bytecodes::polymorphic_send_super_pop: // fall through case Bytecodes::megamorphic_send_super_pop: // fall through blk->super_send(iter.ic()); blk->pop(); break; case Bytecodes::return_tos_pop_0: blk->method_return(0); break; case Bytecodes::return_tos_pop_1: blk->method_return(1); break; case Bytecodes::return_tos_pop_2: blk->method_return(2); break; case Bytecodes::return_tos_pop_n: blk->method_return(iter.byte_at(1)); break; case Bytecodes::return_self_pop_0: blk->push_self(); blk->method_return(0); break; case Bytecodes::return_self_pop_1: blk->push_self(); blk->method_return(1); break; case Bytecodes::return_self_pop_2: blk->push_self(); blk->method_return(2); break; case Bytecodes::return_self_pop_n: blk->push_self(); blk->method_return(iter.byte_at(1)); break; case Bytecodes::return_tos_zap_pop_n: blk->zap_scope(); blk->method_return(iter.byte_at(1)); break; case Bytecodes::return_self_zap_pop_n: blk->zap_scope(); blk->push_self(); blk->method_return(iter.byte_at(1)); break; case Bytecodes::non_local_return_tos_pop_n: blk->nonlocal_return(iter.byte_at(1)); break; case Bytecodes::non_local_return_self_pop_n: blk->push_self(); blk->nonlocal_return(iter.byte_at(1)); break; case Bytecodes::prim_call: // fall through case Bytecodes::prim_call_self: { primitive_desc* pdesc = primitives::lookup((fntype) iter.word_at(1)); PrimitiveCallNode* node = MethodIterator::factory->new_PrimitiveCallNode(_interval->method(), _interval, iter.bci(), iter.next_bci(), pdesc->has_receiver(), NULL, pdesc); // %hack: this assertion fails // assert(pdesc->has_receiver() == (iter.code() == Bytecodes::prim_call_self), "just checking"); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->primitive_call_node(node); next_bci = node->end_bci(); break; } case Bytecodes::predict_prim_call: blk->predict_prim_call(primitives::lookup((fntype) iter.word_at(1)), -1); break; case Bytecodes::prim_call_failure: // fall through case Bytecodes::prim_call_self_failure: { primitive_desc* pdesc = primitives::lookup((fntype) iter.word_at(1)); PrimitiveCallNode* node = MethodIterator::factory->new_PrimitiveCallNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), pdesc->has_receiver(), NULL, pdesc, iter.word_at(1 + oopSize)); assert(pdesc->has_receiver() == (iter.code() == Bytecodes::prim_call_self_failure), "just checking"); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->primitive_call_node(node); next_bci = node->end_bci(); break; } case Bytecodes::predict_prim_call_failure: blk->predict_prim_call( primitives::lookup((fntype) iter.word_at(1)), iter.next_bci() + iter.word_at(1 + oopSize)); break; case Bytecodes::dll_call_sync: { DLLCallNode* node = MethodIterator::factory->new_DLLCallNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), iter.dll_cache()); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->dll_call_node(node); next_bci = node->end_bci(); break; } case Bytecodes::access_send_self: blk->self_send(iter.ic()); break; case Bytecodes::unimplemented_bc: unknown_code(Bytecodes::unimplemented_bc); break; case Bytecodes::prim_call_lookup: // fall through case Bytecodes::prim_call_self_lookup: { symbolOop name = symbolOop(iter.oop_at(1)); assert(name->is_symbol(), "name must be symbolOop"); PrimitiveCallNode* node = MethodIterator::factory->new_PrimitiveCallNode(_interval->method(), _interval, iter.bci(), iter.next_bci(), iter.code() == Bytecodes::prim_call_self_lookup, name, NULL); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->primitive_call_node(node); next_bci = node->end_bci(); break; } case Bytecodes::predict_prim_call_lookup: blk->predict_prim_call(primitives::lookup(symbolOop(iter.word_at(1))), -1); break; case Bytecodes::prim_call_failure_lookup: // fall through case Bytecodes::prim_call_self_failure_lookup: { symbolOop name = symbolOop(iter.oop_at(1)); assert(name->is_symbol(), "name must be symbolOop"); PrimitiveCallNode* node = MethodIterator::factory->new_PrimitiveCallNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), iter.code() == Bytecodes::prim_call_self_failure_lookup, name, NULL, iter.word_at(1 + oopSize)); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->primitive_call_node(node); next_bci = node->end_bci(); break; } case Bytecodes::predict_prim_call_failure_lookup: blk->predict_prim_call( primitives::lookup(symbolOop(iter.word_at(1))), iter.bci() + iter.word_at(1 + oopSize)); break; case Bytecodes::dll_call_async: { DLLCallNode* node = MethodIterator::factory->new_DLLCallNode( _interval->method(), _interval, iter.bci(), iter.next_bci(), iter.dll_cache()); assert(node->end_bci() <= _interval->end_bci(), "just checking"); blk->dll_call_node(node); next_bci = node->end_bci(); break; } case Bytecodes::unimplemented_c7: unknown_code(Bytecodes::unimplemented_c7); break; case Bytecodes::access_send_0: blk->normal_send(iter.ic()); break; case Bytecodes::unimplemented_cc: unknown_code(Bytecodes::unimplemented_cc); break; case Bytecodes::unimplemented_dc: unknown_code(Bytecodes::unimplemented_dc); break; case Bytecodes::special_primitive_send_1_hint: // ignore - only meaningfull for the interpreter break; case Bytecodes::unimplemented_de: unknown_code(Bytecodes::unimplemented_de); break; case Bytecodes::unimplemented_df: unknown_code(Bytecodes::unimplemented_df); break; case Bytecodes::smi_add : // fall through case Bytecodes::smi_sub : // fall through case Bytecodes::smi_mult : // fall through case Bytecodes::smi_div : // fall through case Bytecodes::smi_mod : // fall through case Bytecodes::smi_create_point : // fall through case Bytecodes::smi_equal : // fall through case Bytecodes::smi_not_equal : // fall through case Bytecodes::smi_less : // fall through case Bytecodes::smi_less_equal : // fall through case Bytecodes::smi_greater : // fall through case Bytecodes::smi_greater_equal : // fall through case Bytecodes::objArray_at : // fall through case Bytecodes::objArray_at_put : // fall through case Bytecodes::smi_and : // fall through case Bytecodes::smi_or : // fall through case Bytecodes::smi_xor : // fall through case Bytecodes::smi_shift : blk->normal_send(iter.ic()); break; case Bytecodes::double_equal: blk->double_equal(); break; case Bytecodes::double_tilde: blk->double_not_equal(); break; case Bytecodes::push_global: assert(iter.oop_at(1)->is_association(), "must be an association"); blk->push_global(associationOop(iter.oop_at(1))); break; case Bytecodes::store_global_pop: assert(iter.oop_at(1)->is_association(), "must be an association"); blk->store_global(associationOop(iter.oop_at(1))); blk->pop(); break; case Bytecodes::store_global: assert(iter.oop_at(1)->is_association(), "must be an association"); blk->store_global(associationOop(iter.oop_at(1))); break; case Bytecodes::push_classVar_name: { symbolOop name = symbolOop(iter.oop_at(1)); assert(name->is_symbol(), "must be symbol"); blk->push_classVar_name(name); } break; case Bytecodes::store_classVar_pop_name: { symbolOop name = symbolOop(iter.oop_at(1)); assert(name->is_symbol(), "must be symbol"); blk->store_classVar_name(name); blk->pop(); } break; case Bytecodes::store_classVar_name: { symbolOop name = symbolOop(iter.oop_at(1)); assert(name->is_symbol(), "must be symbol"); blk->store_classVar_name(name); } break; case Bytecodes::unimplemented_fa: unknown_code(Bytecodes::unimplemented_fa); break; case Bytecodes::unimplemented_fb: unknown_code(Bytecodes::unimplemented_fb); break; case Bytecodes::unimplemented_fc: unknown_code(Bytecodes::unimplemented_fc); break; case Bytecodes::unimplemented_fd: unknown_code(Bytecodes::unimplemented_fd); break; case Bytecodes::unimplemented_fe: unknown_code(Bytecodes::unimplemented_fe); break; case Bytecodes::halt: unknown_code(Bytecodes::halt); break; default: ShouldNotReachHere(); } } blk->set_prim_failure(oldFailState); }
slotsOop slotsMap::copy_add_new_slot(slotsOop obj, stringOop name, slotType slot_type, oop contents, oop anno, bool mustAllocate) { assert_slots(obj, "object isn't a slotsOop"); assert(!obj->is_string(), "cannot clone strings!"); bool found; fint newIndex= find_slot_index_for(name, found); assert(!found, "I only add new slots"); slotsMap* new_map= (slotsMap*) insert(newIndex, mustAllocate); if (new_map == NULL) return slotsOop(failedAllocationOop); slotDesc* s= new_map->slot(newIndex); new_map->slots_length= new_map->slots_length->increment(); mapOop new_moop= new_map->enclosing_mapOop(); new_moop->init_mark(); new_map->init_dependents(); slotsOop new_obj; switch (slot_type->slot_type()) { case obj_slot_type: { assert(NakedMethods || !contents->has_code() || slot_type->is_vm_slot(), "adding an assignable slot with code"); // find which offset this slot should be at fint offset= empty_object_size(); for (fint i= newIndex - 1; i >= 0; --i) if (slot(i)->is_obj_slot()) { offset= smiOop(slot(i)->data)->value() + 1; break; } new_obj= obj->is_byteVector() ? (slotsOop) byteVectorOop(obj) -> insert(object_size(obj), offset, 1, mustAllocate, true) : (slotsOop) slotsOop(obj) -> insert(object_size(obj), offset, 1, mustAllocate, true); if (oop(new_obj) == failedAllocationOop) return slotsOop(failedAllocationOop); new_map->shift_obj_slots(as_smiOop(offset), 1); new_map->object_length = new_map->object_length->increment(); new_obj->at_put(offset, contents, false); new_obj->fix_generation(new_map->object_size(new_obj)); contents= as_smiOop(offset); // tagged index of slot data break; } case map_slot_type: new_obj= slotsOop(obj->clone(mustAllocate)); break; case arg_slot_type: assert_smi(contents, "argument index isn't a smiOop"); new_obj= slotsOop(obj->clone(mustAllocate)); break; default: ShouldNotReachHere(); // unexpected slot type } if (oop(new_obj) == failedAllocationOop) return slotsOop(failedAllocationOop); s->init(name, slot_type, contents, anno, false); new_moop->fix_generation(new_moop->size()); new_obj->set_canonical_map(new_map); return new_obj; }
void MissingMethodBuilder::build() { BlockScavenge bs; int argCount = selector->number_of_arguments(); if (argCount > 0) buffer.pushByte(Bytecodes::allocate_temp_1); buffer.pushByte(Bytecodes::push_global); buffer.pushOop(Universe::find_global_association("Message")); buffer.pushByte(Bytecodes::push_self); buffer.pushByte(Bytecodes::push_literal); buffer.pushOop(selector); if (argCount == 0) { buffer.pushByte(Bytecodes::push_literal); buffer.pushOop(oopFactory::new_objArray(0)); } else { buffer.pushByte(Bytecodes::push_global); buffer.pushOop(Universe::find_global_association("Array")); buffer.pushByte(Bytecodes::push_succ_n); buffer.pushByte(argCount - 1); buffer.pushByte(Bytecodes::interpreted_send_1); buffer.pushOop(oopFactory::new_symbol("new:")); buffer.pushOop(as_smiOop(0)); buffer.pushByte(Bytecodes::store_temp_n); buffer.pushByte(0xFF); for (int index = 0; index < argCount; index++) { buffer.pushByte(Bytecodes::push_succ_n); buffer.pushByte(index); buffer.pushByte(Bytecodes::push_arg_n); buffer.pushByte(argCount - index - 1); buffer.pushByte(Bytecodes::interpreted_send_2_pop); buffer.pushOop(oopFactory::new_symbol("at:put:")); buffer.pushOop(as_smiOop(0)); buffer.pushByte(Bytecodes::push_temp_0); } } buffer.pushByte(Bytecodes::interpreted_send_n); buffer.pushByte(3); buffer.pushOop(oopFactory::new_symbol("receiver:selector:arguments:")); buffer.pushOop(as_smiOop(0)); buffer.pushByte(Bytecodes::interpreted_send_self); buffer.pushOop(oopFactory::new_symbol("doesNotUnderstand:")); buffer.pushOop(as_smiOop(0)); switch (argCount) { case 0: buffer.pushByte(Bytecodes::return_tos_pop_0); break; case 1: buffer.pushByte(Bytecodes::return_tos_pop_1); break; case 2: buffer.pushByte(Bytecodes::return_tos_pop_2); break; default: buffer.pushByte(Bytecodes::return_tos_pop_n); buffer.pushByte(argCount); } methodKlass* k = (methodKlass*) Universe::methodKlassObj()->klass_part(); _method = k->constructMethod(selector, 0, // flags argCount, // number of arguments oopFactory::new_objArray(0), // debug info bytes(), oops()); }
Label* CodeGen::indexedBranchCode( Location testMe, LabelList* labels, bool allowPreemption, RegisterState* s) { // if allowPreemption // <testStackOverflowForLoop( afterTest ) > // afterTest: // // <move testMe, t1> // <loadOop smiOop of label length, t2> // tcmp t2, t1 // bvs end // nop // bleu end // nop // call .+8 // add t1, o7, t1 // jump t1, 12, g0 // bra L1 // bra L2 // ... // end: a.Comment("indexedBranchCode"); Label* nlr= NULL; if (allowPreemption) { // Ideally would only do this in the arms that actually do // branch back. // Beware: the stack overflow test could call other code that // could clobber Temp1 and Temp2, so it cannot be in the // middle somewhere. -- dmu Label* afterTest = NULL; testStackOverflowForLoop( afterTest, nlr, s ); // sets afterTest afterTest->define(); } move(Temp1, testMe); a.testl( Tag_Mask, NumberOperand, Temp1); Label end; a.jne( &end ); // goto end if not int a.cmpl((int32)as_smiOop(labels->length()), OopOperand, Temp1); // use unsigned comp to catch negative number a.jnb(&end); // goto end if index is out of bounds, if Temp1 is not below Temp2 Label L(a.printing); a.call(&L); // get pc of next inst onto stack pc_t link_reg_value= a.addr(); L.define(); const int32 indexShift = 2 - Tag_Size; assert(indexShift == 0, "no shift needed"); a.popl(Temp2); const int32 bytes_from_link_value_to_jumps = 7; // indexing is by_two because index is ALREADY 4x value because of tagging a.leal(Temp2, bytes_from_link_value_to_jumps, NumberOperand, Temp1, Assembler::by_two, Temp2); a.jmp(Temp2); pc_t start_of_jumps= a.addr(); assert( bytes_from_link_value_to_jumps == start_of_jumps - link_reg_value, "recount"); for (fint i = 0; i < labels->length(); ++i) { a.jmp(labels->nth(i)); a.hlt(); a.hlt(); a.hlt(); // 8 bytes } pc_t end_of_jumps= a.addr(); assert(end_of_jumps - start_of_jumps == 8 * labels->length(), "8?"); end.define(); return nlr; }
oop bootstrap::get_object() { char type = get_char(); if (type == '0') { int v = get_integer(); // if (TraceBootstrap) std->print_cr("i %d", v); return as_smiOop(v); } if (type == '-') { int v = get_integer(); // if (TraceBootstrap) std->print_cr("i %d", -v); return as_smiOop(-v); } if (type == '3') { int v = get_integer(); // if (TraceBootstrap) std->print_cr("r %d", v); return at(v); } int size = get_integer(); memOop m = as_memOop(Universe::allocate_tenured(size)); // Clear eventual padding area for byteArray, symbol, doubleByteArray. m->raw_at_put(size-1, smiOop_zero); // if (TraceBootstrap) lprintf("%c %d = 0x%lx\n", type, size, m); add(m); switch (type) { // Classes case 'A': KLASS_CASE(set_klassKlass_vtbl) case 'B': KLASS_CASE(set_smiKlass_vtbl) case 'C': KLASS_CASE(set_memOopKlass_vtbl) case 'D': KLASS_CASE(set_byteArrayKlass_vtbl) case 'E': KLASS_CASE(set_doubleByteArrayKlass_vtbl) case 'F': KLASS_CASE(set_objArrayKlass_vtbl) case 'G': KLASS_CASE(set_symbolKlass_vtbl) case 'H': KLASS_CASE(set_doubleKlass_vtbl) case 'I': KLASS_CASE(set_associationKlass_vtbl) case 'J': KLASS_CASE(set_methodKlass_vtbl) case 'K': KLASS_CASE(set_blockClosureKlass_vtbl) case 'L': KLASS_CASE(set_contextKlass_vtbl) case 'M': KLASS_CASE(set_proxyKlass_vtbl) case 'N': KLASS_CASE(set_mixinKlass_vtbl) case 'O': KLASS_CASE(set_weakArrayKlass_vtbl) case 'P': KLASS_CASE(set_processKlass_vtbl) case 'Q': KLASS_CASE(set_doubleValueArrayKlass_vtbl) case 'R': KLASS_CASE(set_vframeKlass_vtbl) // Objects case 'a': OBJECT_ERROR("klass") case 'b': OBJECT_ERROR("smi") case 'c': OBJECT_CASE(memOop); case 'd': OBJECT_CASE(byteArrayOop); case 'e': OBJECT_CASE(doubleByteArrayOop); case 'f': OBJECT_CASE(objArrayOop) case 'g': SYMBOL_CASE(symbolOop); case 'h': OBJECT_CASE(doubleOop); case 'i': OBJECT_CASE(associationOop); case 'j': OBJECT_CASE(methodOop); case 'k': OBJECT_ERROR("blockClosure") case 'l': OBJECT_ERROR("context") case 'm': OBJECT_ERROR("proxy") case 'n': OBJECT_CASE(mixinOop) case 'o': OBJECT_ERROR("weakArrayOop") case 'p': OBJECT_CASE(processOop) default: fatal("unknown object type"); } return m; }
PRIM_DECL_1(doubleByteArrayPrimitives::hash, oop receiver) { PROLOGUE_1("intern", receiver); ASSERT_RECEIVER; return as_smiOop(doubleByteArrayOop(receiver)->hash_value()); }
Label* CodeGen::indexedBranchCode( Location testMe, LabelList* labels, bool allowPreemption, RegisterState* s) { // if allowPreemption // <testStackOverflowForLoop( afterTest ) > // afterTest: // // <move testMe, t1> // <loadOop smiOop of label length, t2> // tcmp t2, t1 // bvs end // nop // bleu end // nop // call .+8 // add t1, o7, t1 // jump t1, 12, g0 // bra L1 // bra L2 // ... // end: Label* nlr= NULL; if (allowPreemption) { // Ideally would only do this in the arms that actually do // branch back. // Beware: the stack overflow test could call other code that // could clobber Temp1 and Temp2, so it cannot be in the // middle somewhere. -- dmu Label* afterTest; testStackOverflowForLoop( afterTest, nlr, s ); afterTest->define(); } move( Temp1, testMe, false); loadOop( Temp2, as_smiOop(labels->length())); a.TSubCCR( Temp2, Temp1, G0); Label* end = a.BvsForward(false); a.Nop(); end->unify( a.BleuForward(false) ); a.Nop(); pc_t cra= a.addr(); const int32 bytesFromCallToJump = 4 * sizeof(int32); const int32 bytesFromCallToInstAfterDelay = 2 * sizeof(int32); // only on V9: a.ReadPC(Temp2); a.CallN( a.addr() + bytesFromCallToInstAfterDelay); const int32 indexShift = 2 - Tag_Size; assert(indexShift == 0, "no shift needed"); a.AddR( Temp1, CalleeReturnAddr, Temp1); // in the delay slot assert( a.addr() - cra == bytesFromCallToInstAfterDelay, "recount instructions"); a.JmpLI( Temp1, bytesFromCallToJump - (Int_Tag << indexShift), G0); a.Nop(); // delay slot for jmp, cannot have branch here assert( a.addr() - cra == bytesFromCallToJump, "recount instructions"); for (fint i = 0; i < labels->length(); ++i) { a.Bra(labels->nth(i), true); } end->define(); return nlr; }
void set_length(smi len) { *length_addr() = (oop) as_smiOop(len); }
extern "C" volatile void* handleCallBack(int index, int params) { DeltaProcess* proc = NULL; if (Universe::callBack_receiver()->is_nil()) { warning("callBack receiver is not set"); } int low = get_unsigned_bitfield(params, 0, 16); int high = get_unsigned_bitfield(params, 16, 16); if (DeltaProcess::active()->thread_id() != os::current_thread_id()) { // We'are now back in a asynchronous DLL call so give up the control // Fix this: // remove warning when it has been tested proc = Processes::find_from_thread_id(os::current_thread_id()); assert(proc, "process must be present"); DLLs::exit_async_call(&proc); } DeltaProcess::active()->setIsCallback(true); oop res = Delta::call(Universe::callBack_receiver(), Universe::callBack_selector(), as_smiOop(index), as_smiOop(high), as_smiOop(low)); assert(DeltaProcess::active()->thread_id() == os::current_thread_id(), "check for process torch"); void* result; // convert return result if (have_nlr_through_C) { // Continues the NLR after at the next Delta frame BaseHandle* handle = DeltaProcess::active()->firstHandle(); if (handle && ((char*) handle < (char*)DeltaProcess::active()->last_Delta_fp())) handle->pop(); ErrorHandler::continue_nlr_in_delta(); } if (res->is_smi()) { result = (void*) smiOop(res)->value(); } else if (res->is_proxy()) { result = (void*) proxyOop(res)->get_pointer(); } else { warning("Wrong return type for call back, returning NULL"); result = NULL; } // Return value has to be converted before we transfer control to another // thread. if (proc) { // We'are now back in a asynchronous DLL call so give up the control proc->resetStepping(); proc->transfer_and_continue(); } // Call Delta level error routine return result; }
void HCodeBuffer::pushByte(unsigned char op) { if (isAligned()) _oops->append(as_smiOop(0)); _bytes->append(op); }
void set_time_stamp(int t) { STORE_OOP(&addr()->_time_stamp, as_smiOop(t)); }
void slotsMap::switch_pointer_in_map(oop* where, oop to) { if (where == &annotation) { set_annotation(to); return; } Map::switch_pointer_in_map(where, to); } void slotsMap::shift_obj_slots(smiOop offset, fint delta) { FOR_EACH_SLOTDESC(this, slot) { if (slot->type->is_obj_slot() && smiOop(slot->data) >= offset) Memory->store(&slot->data, as_smiOop(smiOop(slot->data)->value() + delta)); } } oop slotsMap::clone(oop obj, bool mustAllocate, oop genObj) { assert_slots(obj, "not a slots object"); assert(!is_byteVector(), "should override this method for a byte vector"); slotsOop p= (slotsOop) slotsOop(obj)->copy(object_size(obj), mustAllocate, genObj); if (oop(p) != failedAllocationOop) p->init_mark(); return p; } oop slotsMap::cloneSize(oop obj, fint length, bool mustAllocate, oop filler) { Unused(length); Unused(mustAllocate); Unused(filler); ShouldNotCallThis(); // object isn't a vector
SExpr* SPrimScope::inlineIntArithmetic() { ArithOpCode op = opcode_for_selector(_selector); bool intRcvr = receiver->hasMap() && receiver->map() == Memory->smi_map; SExpr* arg = args->nth(0); bool intArg = arg->hasMap() && arg->map() == Memory->smi_map; if ( intArg && arg->isConstantSExpr() && intRcvr && arg->constant() == as_smiOop(0) && can_fold_rcvr_op_zero_to_zero(op)) { if (PrintInlining) lprintf("%*s*constant-folding %s: 0\n", (void*)(depth-1), "", ArithOpName[op]); return receiver; } if (PrintInlining) lprintf("%*s*inlining %s:\n", (void*)(depth-1), "", ArithOpName[op]); if (!TArithRRNode::isOpInlinable(op)) return NULL; NodeGen* n = theNodeGen; Node* arith = n->append(new TArithRRNode(op, receiver->preg(), arg->preg(), resultPR, intRcvr, intArg)); // success case - no overflow, int tags MergeNode* ok = (MergeNode*)n->append(new MergeNode("inlineIntArithmetic ok")); SExpr* succExpr = new MapSExpr(Memory->smi_map->enclosing_mapOop(), resultPR, ok); // merge of success & failure branches MergeNode* done = (MergeNode*)ok->append(new MergeNode("inlineIntArithmetic done")); // failure case n->current = arith->append1(new NopNode); if (theSIC->useUncommonTraps && sender()->rscope->isUncommonAt(sender()->bci(), true)) { n->uncommonBranch(currentExprStack(0), true); n->current = done; if (PrintInlining) { lprintf("%*s*making arithmetic failure uncommon\n", (void*)(depth-1), ""); } return succExpr; } else { fint b = bci(); PReg* error = new SAPReg(_sender, b, b); if (intRcvr && intArg) { // must be overflow n->loadOop(VMString[OVERFLOWERROR], error); } else { arith->hasSideEffects_now = true; // may fail, so can't eliminate if (intRcvr || TARGET_ARCH == I386_ARCH) { // arg & TagMask already done by TArithRRNode // I386 does 'em all } else { PReg* t = new TempPReg(this, Temp1, false, true); n->append(new ArithRCNode(AndCCArithOp, t, Tag_Mask, t)); n->current->hasSideEffects_now = true; } // Note: this code assumes that condcode EQ means overflow Node* branch = n->append(new BranchNode(EQBranchOp)); // no overflow, must be type error n->loadOop(VMString[BADTYPEERROR], error); MergeNode* cont = (MergeNode*)n->append( new MergeNode("inlineIntArithmetic cont")); // overflow error PReg* err = new_ConstPReg(_sender, VMString[OVERFLOWERROR]); n->current = branch->append1(new AssignNode(err, error)); n->branch(cont); } Node* dummy; SExpr* failExpr = genPrimFailure(NULL, error, dummy, done, resultPR); assert(done, "merge should always exist"); return succExpr->mergeWith(failExpr, done); } }
oop objVectorOopClass::ov_size_prim(oop rcvr) { if (!rcvr->is_objVector()) return ErrorCodes::vmString_prim_error(BADTYPEERROR); return as_smiOop(objVectorOop(rcvr)->length()); }