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())); }
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()); } }
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; }