SharkValue* xstack(int slot) { SharkValue *value = current_state()->stack(slot); assert(value != NULL, "shouldn't be"); assert(value->is_one_word() || (slot > 0 && current_state()->stack(slot - 1) == NULL), "should be"); return value; }
SharkValue* pop() { int size = current_state()->stack(0) == NULL ? 2 : 1; if (size == 2) xpop(); SharkValue *value = xpop(); assert(value && value->size() == size, "should be"); return value; }
SharkValue* local(int index) { SharkValue *value = current_state()->local(index); assert(value != NULL, "shouldn't be"); assert(value->is_one_word() || (index + 1 < max_locals() && current_state()->local(index + 1) == NULL), "should be"); return value; }
void SharkCacher::process_local_slot(int index, SharkValue** addr, int offset) { SharkValue *value = *addr; // Read the value from the frame if necessary if (local_slot_needs_read(index, value)) { *addr = SharkValue::create_generic( value->type(), read_value_from_frame( SharkType::to_stackType(value->basic_type()), adjusted_offset(value, offset)), value->zero_checked()); } }
void SharkOSREntryCacher::process_local_slot(int index, SharkValue** addr, int offset) { SharkValue *value = *addr; // Read the value from the OSR buffer if necessary if (local_slot_needs_read(index, value)) { *addr = SharkValue::create_generic( value->type(), builder()->CreateLoad( CreateAddressOfOSRBufEntry( adjusted_offset(value, max_locals() - 1 - index), SharkType::to_stackType(value->basic_type()))), value->zero_checked()); } }
void SharkIntrinsics::do_Math_minmax(ICmpInst::Predicate p) { // Pop the arguments SharkValue *sb = state()->pop(); SharkValue *sa = state()->pop(); Value *a = sa->jint_value(); Value *b = sb->jint_value(); // Perform the test BasicBlock *ip = builder()->GetBlockInsertionPoint(); BasicBlock *return_a = builder()->CreateBlock(ip, "return_a"); BasicBlock *return_b = builder()->CreateBlock(ip, "return_b"); BasicBlock *done = builder()->CreateBlock(ip, "done"); builder()->CreateCondBr(builder()->CreateICmp(p, a, b), return_a, return_b); builder()->SetInsertPoint(return_a); builder()->CreateBr(done); builder()->SetInsertPoint(return_b); builder()->CreateBr(done); builder()->SetInsertPoint(done); PHINode *phi = builder()->CreatePHI(a->getType(), 0, "result"); phi->addIncoming(a, return_a); phi->addIncoming(b, return_b); // Push the result state()->push( SharkValue::create_jint( phi, sa->zero_checked() && sb->zero_checked())); }
SharkValue* pop_result(BasicType type) { SharkValue *result = pop(); #ifdef ASSERT switch (result->basic_type()) { case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT: assert(type == T_INT, "type mismatch"); break; case T_ARRAY: assert(type == T_OBJECT, "type mismatch"); break; default: assert(result->basic_type() == type, "type mismatch"); } #endif // ASSERT return result; }
void SharkDecacher::process_stack_slot(int index, SharkValue** addr, int offset) { SharkValue *value = *addr; // Write the value to the frame if necessary if (stack_slot_needs_write(index, value)) { write_value_to_frame( SharkType::to_stackType(value->basic_type()), value->generic_value(), adjusted_offset(value, offset)); } // Record the value in the oopmap if necessary if (stack_slot_needs_oopmap(index, value)) { oopmap()->set_oop(slot2reg(offset)); } // Record the value in the debuginfo if necessary if (stack_slot_needs_debuginfo(index, value)) { exparray()->append(slot2lv(offset, stack_location_type(index, addr))); } }
static Location::Type location_type(SharkValue** addr, bool maybe_two_word) { // low addresses this end // Type 32-bit 64-bit // ---------------------------------------------------- // stack[0] local[3] jobject oop oop // stack[1] local[2] NULL normal lng // stack[2] local[1] jlong normal invalid // stack[3] local[0] jint normal normal // // high addresses this end SharkValue *value = *addr; if (value) { if (value->is_jobject()) return Location::oop; #ifdef _LP64 if (value->is_two_word()) return Location::invalid; #endif // _LP64 return Location::normal; } else { if (maybe_two_word) { value = *(addr - 1); if (value && value->is_two_word()) { #ifdef _LP64 if (value->is_jlong()) return Location::lng; if (value->is_jdouble()) return Location::dbl; ShouldNotReachHere(); #else return Location::normal; #endif // _LP64 } } return Location::invalid; } }
SharkConstant::SharkConstant(ciConstant constant, ciType *type) { SharkValue *value = NULL; switch (constant.basic_type()) { case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT: case T_INT: value = SharkValue::jint_constant(constant.as_int()); break; case T_LONG: value = SharkValue::jlong_constant(constant.as_long()); break; case T_FLOAT: value = SharkValue::jfloat_constant(constant.as_float()); break; case T_DOUBLE: value = SharkValue::jdouble_constant(constant.as_double()); break; case T_OBJECT: case T_ARRAY: break; case T_ILLEGAL: // out of memory _is_loaded = false; return; default: tty->print_cr("Unhandled type %s", type2name(constant.basic_type())); ShouldNotReachHere(); } // Handle primitive types. We create SharkValues for these // now; doing so doesn't emit any code, and it allows us to // delegate a bunch of stuff to the SharkValue code. if (value) { _value = value; _is_loaded = true; _is_nonzero = value->zero_checked(); _is_two_word = value->is_two_word(); return; } // Handle reference types. This is tricky because some // ciObjects are psuedo-objects that refer to oops which // have yet to be created. We need to spot the unloaded // objects (which differ between ldc* and get*, thanks!) ciObject *object = constant.as_object(); assert(type != NULL, "shouldn't be"); if (object->is_klass()) { // The constant returned for a klass is the ciKlass // for the entry, but we want the java_mirror. ciKlass *klass = object->as_klass(); if (!klass->is_loaded()) { _is_loaded = false; return; } object = klass->java_mirror(); } if (object->is_null_object() || !object->can_be_constant()) { _is_loaded = false; return; } _value = NULL; _object = object; _type = type; _is_loaded = true; _is_nonzero = true; _is_two_word = false; }