Shark direct call improvements
Gary Benson
gbenson at redhat.com
Wed Jun 3 06:36:04 PDT 2009
Hi all,
This commit replaces the interpreter-style lookup of the callee in
the constant pool with a server-JIT-style callee inlined in the code
buffer for direct calls (ie invokestatic, invokespecial, and final
invokevirtual). This gives a small speedup in itself, but opens the
door to a ton of other optimizations.
Cheers,
Gary
--
http://gbenson.net/
-------------- next part --------------
diff -r e01a6da1a425 -r 6bbac4cbc210 ChangeLog
--- a/ChangeLog Tue Jun 02 15:41:45 2009 +0100
+++ b/ChangeLog Wed Jun 03 14:32:52 2009 +0100
@@ -1,3 +1,33 @@
+2009-06-03 Gary Benson <gbenson at redhat.com>
+
+ * ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp
+ (MacroAssembler::store_oop): New method.
+ * ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp
+ (MacroAssembler::store_oop): Likewise.
+
+ * ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp
+ (Relocation::pd_address_in_code): Implement.
+
+ * ports/hotspot/src/share/vm/shark/sharkCompiler.cpp
+ (SharkCompiler::compile_method): Create CodeBuffer
+ with space for relocations.
+
+ * ports/hotspot/src/share/vm/shark/sharkFunction.hpp
+ (SharkFunction::code_offset): Renamed as...
+ (SharkFunction::create_unique_pc_offset): New method.
+ (SharkFunction::CreateAddressOfCodeBufferEntry): Likewise.
+ (SharkFunction::CreateAddressOfOopInCodeBuffer): Likewise.
+
+ * ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp
+ (SharkDecacher::start_frame): Updated to use new offset code.
+ (SharkDecacher::start_stack): Likewise.
+
+ * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
+ (SharkTopLevelBlock::scan_for_traps): Direct calls need no
+ checking.
+ (SharkTopLevelBlock::get_direct_callee): Replace constant
+ pool lookup with oop load from CodeBuffer.
+
2009-06-02 Gary Benson <gbenson at redhat.com>
* ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp Wed Jun 03 14:32:52 2009 +0100
@@ -60,6 +60,12 @@
sync();
}
+void MacroAssembler::store_oop(jobject obj)
+{
+ code_section()->relocate(pc(), oop_Relocation::spec_for_immediate());
+ emit_address((address) obj);
+}
+
static void _UnimplementedStub()
{
report_unimplemented(__FILE__, __LINE__);
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp Wed Jun 03 14:32:52 2009 +0100
@@ -1,6 +1,6 @@
/*
* Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
- * Copyright 2007, 2008 Red Hat, Inc.
+ * Copyright 2007, 2008, 2009 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,8 +45,10 @@
void align(int modulus);
void bang_stack_with_offset(int offset);
bool needs_explicit_null_check(intptr_t offset);
+
public:
void advance(int bytes);
+ void store_oop(jobject obj);
};
#ifdef ASSERT
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/cpu/zero/vm/relocInfo_zero.cpp Wed Jun 03 14:32:52 2009 +0100
@@ -48,7 +48,8 @@
address* Relocation::pd_address_in_code()
{
- Unimplemented();
+ // Relocations in Shark are just stored directly
+ return (address *) addr();
}
int Relocation::pd_breakpoint_size()
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp Wed Jun 03 14:32:52 2009 +0100
@@ -31,7 +31,7 @@
void SharkDecacher::start_frame()
{
// Start recording the debug information
- _pc_offset = function()->code_offset();
+ _pc_offset = function()->create_unique_pc_offset();
_oopmap = new OopMap(
oopmap_slot_munge(function()->oopmap_frame_size()),
oopmap_slot_munge(function()->arg_size()));
@@ -119,8 +119,7 @@
{
// Record the PC
builder()->CreateStore(
- builder()->CreateAdd(
- function()->base_pc(), LLVMValue::intptr_constant(pc_offset())),
+ function()->CreateAddressOfCodeBufferEntry(pc_offset()),
function()->CreateAddressOfFrameEntry(offset));
}
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkCompiler.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp Wed Jun 03 14:32:52 2009 +0100
@@ -116,8 +116,7 @@
env->set_dependencies(new Dependencies(env));
// Create the CodeBuffer and MacroAssembler
- BufferBlob *bb = BufferBlob::create("shark_temp", 256 * K);
- CodeBuffer cb(bb->instructions_begin(), bb->instructions_size());
+ CodeBuffer cb("Shark", 256 * K, 64 * K);
cb.initialize_oop_recorder(env->oop_recorder());
MacroAssembler *masm = new MacroAssembler(&cb);
@@ -148,9 +147,6 @@
env->comp_level(),
false,
false);
-
- // Free the BufferBlob
- BufferBlob::free(bb);
}
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkFunction.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp Wed Jun 03 14:32:52 2009 +0100
@@ -137,6 +137,28 @@
return flow()->method();
}
+ // CodeBuffer interface
+ public:
+ int create_unique_pc_offset() const
+ {
+ int offset = masm()->offset();
+ masm()->advance(1);
+ return offset;
+ }
+ llvm::Value* CreateAddressOfCodeBufferEntry(int offset) const
+ {
+ return builder()->CreateAdd(base_pc(), LLVMValue::intptr_constant(offset));
+ }
+ llvm::Value* CreateAddressOfOopInCodeBuffer(ciObject* object) const
+ {
+ masm()->align(BytesPerWord);
+ int offset = masm()->offset();
+ masm()->store_oop(object->encoding());
+ return builder()->CreateIntToPtr(
+ CreateAddressOfCodeBufferEntry(offset),
+ llvm::PointerType::getUnqual(SharkType::jobject_type()));
+ }
+
// Block management
private:
llvm::BasicBlock* _block_insertion_point;
@@ -217,17 +239,6 @@
private:
llvm::Value* CreateBuildFrame();
- // OopMap support
- public:
- // Every time a new, distinct pc is required, an extra byte is
- // emitted into the codebuffer
- int code_offset() const
- {
- int offset = masm()->offset();
- masm()->advance(1); // keeps PCs unique
- return offset;
- }
-
private:
int _extended_frame_size;
int _stack_slots_offset;
diff -r e01a6da1a425 -r 6bbac4cbc210 ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Tue Jun 02 15:41:45 2009 +0100
+++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jun 03 14:32:52 2009 +0100
@@ -91,28 +91,26 @@
index = iter()->get_field_index();
break;
- case Bytecodes::_invokespecial:
- case Bytecodes::_invokestatic:
case Bytecodes::_invokevirtual:
+ method = iter()->get_method(will_link);
+ assert(will_link, "typeflow responsibility");
+
+ // If this is a non-final invokevirtual then we need to
+ // check that its holder is linked, because its vtable
+ // won't have been set up otherwise.
+ if (!method->is_final_method() && !method->holder()->is_linked()) {
+ set_trap(
+ Deoptimization::make_trap_request(
+ Deoptimization::Reason_uninitialized,
+ Deoptimization::Action_reinterpret), bci());
+ return;
+ }
+ break;
+
case Bytecodes::_invokeinterface:
method = iter()->get_method(will_link);
assert(will_link, "typeflow responsibility");
- // If this is a non-final invokevirtual then there won't
- // be a pool access. We do need to check that its holder
- // is linked, however, because its vtable won't have been
- // set up otherwise.
- if (bc() == Bytecodes::_invokevirtual && !method->is_final_method()) {
- if (!method->holder()->is_linked()) {
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_uninitialized,
- Deoptimization::Action_reinterpret), bci());
- return;
- }
- break;
- }
-
// Continue to the check
index = iter()->get_method_index();
break;
@@ -897,15 +895,10 @@
// invokevirtual is direct in some circumstances.
Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method)
{
- SharkConstantPool constants(this);
- Value *cache = constants.cache_entry_at(iter()->get_method_index());
- return builder()->CreateValueOfStructEntry(
- cache,
- bc() == Bytecodes::_invokevirtual ?
- ConstantPoolCacheEntry::f2_offset() :
- ConstantPoolCacheEntry::f1_offset(),
- SharkType::methodOop_type(),
- "callee");
+ return builder()->CreateLoad(
+ builder()->CreateBitCast(
+ function()->CreateAddressOfOopInCodeBuffer(method),
+ PointerType::getUnqual(SharkType::methodOop_type())), "callee");
}
// Non-direct virtual calls are handled here
More information about the distro-pkg-dev
mailing list