Mercurial > hg > graal-compiler
view src/share/vm/shark/sharkValue.hpp @ 2149:7e37af9d69ef
7011379: G1: overly long concurrent marking cycles
Summary: This changeset introduces filtering of SATB buffers at the point when they are about to be enqueued. If this filtering clears enough entries on each buffer, the buffer can then be re-used and not enqueued. This cuts down the number of SATB buffers that need to be processed by the concurrent marking threads.
Reviewed-by: johnc, ysr
author | tonyp |
---|---|
date | Wed, 19 Jan 2011 09:35:17 -0500 |
parents | f95d63e2154a |
children |
line wrap: on
line source
/* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #ifndef SHARE_VM_SHARK_SHARKVALUE_HPP #define SHARE_VM_SHARK_SHARKVALUE_HPP #include "ci/ciType.hpp" #include "memory/allocation.hpp" #include "shark/llvmHeaders.hpp" #include "shark/llvmValue.hpp" #include "shark/sharkType.hpp" // Items on the stack and in local variables are tracked using // SharkValue objects. // // All SharkValues are one of two core types, SharkNormalValue // and SharkAddressValue, but no code outside this file should // ever refer to those directly. The split is because of the // way JSRs are handled: the typeflow pass expands them into // multiple copies, so the return addresses pushed by jsr and // popped by ret only exist at compile time. Having separate // classes for these allows us to check that our jsr handling // is correct, via assertions. // // There is one more type, SharkPHIValue, which is a subclass // of SharkNormalValue with a couple of extra methods. Use of // SharkPHIValue outside of this file is acceptable, so long // as it is obtained via SharkValue::as_phi(). class SharkBuilder; class SharkPHIValue; class SharkValue : public ResourceObj { protected: SharkValue() {} // Cloning public: virtual SharkValue* clone() const = 0; // Casting public: virtual bool is_phi() const; virtual SharkPHIValue* as_phi(); // Comparison public: virtual bool equal_to(SharkValue* other) const = 0; // Type access public: virtual BasicType basic_type() const = 0; virtual ciType* type() const; virtual bool is_jint() const; virtual bool is_jlong() const; virtual bool is_jfloat() const; virtual bool is_jdouble() const; virtual bool is_jobject() const; virtual bool is_jarray() const; virtual bool is_address() const; virtual int size() const = 0; bool is_one_word() const { return size() == 1; } bool is_two_word() const { return size() == 2; } // Typed conversion from SharkValues public: virtual llvm::Value* jint_value() const; virtual llvm::Value* jlong_value() const; virtual llvm::Value* jfloat_value() const; virtual llvm::Value* jdouble_value() const; virtual llvm::Value* jobject_value() const; virtual llvm::Value* jarray_value() const; virtual int address_value() const; // Typed conversion to SharkValues public: static SharkValue* create_jint(llvm::Value* value, bool zero_checked) { assert(value->getType() == SharkType::jint_type(), "should be"); return create_generic(ciType::make(T_INT), value, zero_checked); } static SharkValue* create_jlong(llvm::Value* value, bool zero_checked) { assert(value->getType() == SharkType::jlong_type(), "should be"); return create_generic(ciType::make(T_LONG), value, zero_checked); } static SharkValue* create_jfloat(llvm::Value* value) { assert(value->getType() == SharkType::jfloat_type(), "should be"); return create_generic(ciType::make(T_FLOAT), value, false); } static SharkValue* create_jdouble(llvm::Value* value) { assert(value->getType() == SharkType::jdouble_type(), "should be"); return create_generic(ciType::make(T_DOUBLE), value, false); } static SharkValue* create_jobject(llvm::Value* value, bool zero_checked) { assert(value->getType() == SharkType::oop_type(), "should be"); return create_generic(ciType::make(T_OBJECT), value, zero_checked); } // Typed conversion from constants of various types public: static SharkValue* jint_constant(jint value) { return create_jint(LLVMValue::jint_constant(value), value != 0); } static SharkValue* jlong_constant(jlong value) { return create_jlong(LLVMValue::jlong_constant(value), value != 0); } static SharkValue* jfloat_constant(jfloat value) { return create_jfloat(LLVMValue::jfloat_constant(value)); } static SharkValue* jdouble_constant(jdouble value) { return create_jdouble(LLVMValue::jdouble_constant(value)); } static SharkValue* null() { return create_jobject(LLVMValue::null(), false); } static inline SharkValue* address_constant(int bci); // Type-losing conversions -- use with care! public: virtual llvm::Value* generic_value() const = 0; virtual llvm::Value* intptr_value(SharkBuilder* builder) const; static inline SharkValue* create_generic(ciType* type, llvm::Value* value, bool zero_checked); static inline SharkValue* create_phi(ciType* type, llvm::PHINode* phi, const SharkPHIValue* parent = NULL); // Phi-style stuff public: virtual void addIncoming(SharkValue* value, llvm::BasicBlock* block); virtual SharkValue* merge(SharkBuilder* builder, SharkValue* other, llvm::BasicBlock* other_block, llvm::BasicBlock* this_block, const char* name) = 0; // Repeated null and divide-by-zero check removal public: virtual bool zero_checked() const; virtual void set_zero_checked(bool zero_checked); }; class SharkNormalValue : public SharkValue { friend class SharkValue; protected: SharkNormalValue(ciType* type, llvm::Value* value, bool zero_checked) : _type(type), _llvm_value(value), _zero_checked(zero_checked) {} private: ciType* _type; llvm::Value* _llvm_value; bool _zero_checked; private: llvm::Value* llvm_value() const { return _llvm_value; } // Cloning public: SharkValue* clone() const; // Comparison public: bool equal_to(SharkValue* other) const; // Type access public: ciType* type() const; BasicType basic_type() const; int size() const; public: bool is_jint() const; bool is_jlong() const; bool is_jfloat() const; bool is_jdouble() const; bool is_jobject() const; bool is_jarray() const; // Typed conversions to LLVM values public: llvm::Value* jint_value() const; llvm::Value* jlong_value() const; llvm::Value* jfloat_value() const; llvm::Value* jdouble_value() const; llvm::Value* jobject_value() const; llvm::Value* jarray_value() const; // Type-losing conversions, use with care public: llvm::Value* generic_value() const; llvm::Value* intptr_value(SharkBuilder* builder) const; // Phi-style stuff public: SharkValue* merge(SharkBuilder* builder, SharkValue* other, llvm::BasicBlock* other_block, llvm::BasicBlock* this_block, const char* name); // Repeated null and divide-by-zero check removal public: bool zero_checked() const; void set_zero_checked(bool zero_checked); }; class SharkPHIValue : public SharkNormalValue { friend class SharkValue; protected: SharkPHIValue(ciType* type, llvm::PHINode* phi, const SharkPHIValue *parent) : SharkNormalValue(type, phi, parent && parent->zero_checked()), _parent(parent), _all_incomers_zero_checked(true) {} private: const SharkPHIValue* _parent; bool _all_incomers_zero_checked; private: const SharkPHIValue* parent() const { return _parent; } bool is_clone() const { return parent() != NULL; } public: bool all_incomers_zero_checked() const { if (is_clone()) return parent()->all_incomers_zero_checked(); return _all_incomers_zero_checked; } // Cloning public: SharkValue* clone() const; // Casting public: bool is_phi() const; SharkPHIValue* as_phi(); // Phi-style stuff public: void addIncoming(SharkValue *value, llvm::BasicBlock* block); }; class SharkAddressValue : public SharkValue { friend class SharkValue; protected: SharkAddressValue(int bci) : _bci(bci) {} private: int _bci; // Cloning public: SharkValue* clone() const; // Comparison public: bool equal_to(SharkValue* other) const; // Type access public: BasicType basic_type() const; int size() const; bool is_address() const; // Typed conversion from SharkValues public: int address_value() const; // Type-losing conversion -- use with care! public: llvm::Value* generic_value() const; // Phi-style stuff public: void addIncoming(SharkValue *value, llvm::BasicBlock* block); SharkValue* merge(SharkBuilder* builder, SharkValue* other, llvm::BasicBlock* other_block, llvm::BasicBlock* this_block, const char* name); }; // SharkValue methods that can't be declared above inline SharkValue* SharkValue::create_generic(ciType* type, llvm::Value* value, bool zero_checked) { return new SharkNormalValue(type, value, zero_checked); } inline SharkValue* SharkValue::create_phi(ciType* type, llvm::PHINode* phi, const SharkPHIValue* parent) { return new SharkPHIValue(type, phi, parent); } inline SharkValue* SharkValue::address_constant(int bci) { return new SharkAddressValue(bci); } #endif // SHARE_VM_SHARK_SHARKVALUE_HPP