From 6ef59d5520a1a23bcd9ed991ae7185afeec469f0 Mon Sep 17 00:00:00 2001 From: Constellation Date: Mon, 28 Jan 2013 04:10:05 +0900 Subject: [PATCH] Extract ConstantPool to iv/lv5/railgun/constant_pool.h --- iv/lv5/railgun/code.h | 1 + iv/lv5/railgun/compiler.h | 162 +---------------------------- iv/lv5/railgun/constant_pool.h | 179 +++++++++++++++++++++++++++++++++ iv/lv5/railgun/fwd.h | 1 + 4 files changed, 182 insertions(+), 161 deletions(-) create mode 100644 iv/lv5/railgun/constant_pool.h diff --git a/iv/lv5/railgun/code.h b/iv/lv5/railgun/code.h index 2e86ff0d..e5017d75 100644 --- a/iv/lv5/railgun/code.h +++ b/iv/lv5/railgun/code.h @@ -28,6 +28,7 @@ class Code : public radio::HeapObject { EVAL }; friend class Compiler; + friend class ConstantPool; friend class breaker::Compiler; typedef GCVector::type Names; typedef CoreData::Data Data; diff --git a/iv/lv5/railgun/compiler.h b/iv/lv5/railgun/compiler.h index 40d61463..5888e1cb 100644 --- a/iv/lv5/railgun/compiler.h +++ b/iv/lv5/railgun/compiler.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include namespace iv { @@ -125,167 +126,6 @@ class Compiler : private core::Noncopyable, public AstVisitor { std::size_t from_; }; - class ConstantPool { - // Bytecode register size is very limited. - // So probably, constant register may be overflown sometimes. - // When constant register is overflown, we can use LOAD_CONST instead of - // constant register. - public: - static const uint32_t kEmpty = UINT32_MAX; - - typedef std::unordered_map JSStringToIndexMap; - typedef std::unordered_map< - double, - int32_t, - std::hash, JSDoubleEquals> JSDoubleToIndexMap; - - ConstantPool(Context* ctx) - : ctx_(ctx), - code_(NULL), - jsstring_to_index_map_(), - double_to_index_map_(), - undefined_index_(), - null_index_(), - true_index_(), - false_index_(), - empty_index_() { - } - - void Init(Code* code) { - code_ = code; - jsstring_to_index_map_.clear(); - double_to_index_map_.clear(); - undefined_index_ = kEmpty; - null_index_ = kEmpty; - true_index_ = kEmpty; - false_index_ = kEmpty; - empty_index_ = kEmpty; - } - - uint32_t undefined_index() { - if (undefined_index_ != kEmpty) { - return undefined_index_; - } - undefined_index_ = AddConstant(JSUndefined); - return undefined_index_; - } - - uint32_t null_index() { - if (null_index_ != kEmpty) { - return null_index_; - } - null_index_ = AddConstant(JSNull); - return null_index_; - } - - uint32_t true_index() { - if (true_index_ != kEmpty) { - return true_index_; - } - true_index_ = AddConstant(JSTrue); - return true_index_; - } - - uint32_t false_index() { - if (false_index_ != kEmpty) { - return false_index_; - } - false_index_ = AddConstant(JSFalse); - return false_index_; - } - - uint32_t empty_index() { - if (empty_index_ != kEmpty) { - return empty_index_; - } - empty_index_ = AddConstant(JSEmpty); - return empty_index_; - } - - uint32_t string_index(const core::UString& str) { - const JSStringToIndexMap::const_iterator it = - jsstring_to_index_map_.find(str); - - if (it != jsstring_to_index_map_.end()) { - // duplicate constant - return it->second; - } - - // new constant value - Error::Dummy dummy; - const uint32_t index = AddConstant( - JSString::New( - ctx_, - str.begin(), - str.end(), - core::character::IsASCII(str.begin(), str.end()), &dummy)); - jsstring_to_index_map_.insert(std::make_pair(str, index)); - return index; - } - - uint32_t string_index(const StringLiteral* str) { - return string_index(core::ToUString(str->value())); - } - - uint32_t string_index(const core::StringPiece& str) { - return string_index(core::ToUString(str)); - } - - uint32_t string_index(const core::UStringPiece& str) { - return string_index(core::UString(str)); - } - - uint32_t number_index(double val) { - const JSDoubleToIndexMap::const_iterator it = - double_to_index_map_.find(val); - - if (it != double_to_index_map_.end()) { - // duplicate constant pool - return it->second; - } - - // new constant value - const uint32_t index = AddConstant(val); - double_to_index_map_.insert(std::make_pair(val, index)); - return index; - } - - uint32_t Lookup(JSVal constant) { - if (constant.IsString()) { - return string_index(constant.string()->GetUString()); - } else if (constant.IsNumber()) { - return number_index(constant.number()); - } else if (constant.IsUndefined()) { - return undefined_index(); - } else if (constant.IsNull()) { - return null_index(); - } else if (constant.IsBoolean()) { - return (constant.boolean()) ? true_index() : false_index(); - } else if (constant.IsEmpty()) { - return empty_index(); - } - UNREACHABLE(); - return 0; // makes compiler happy - } - - private: - uint32_t AddConstant(JSVal value) { - const uint32_t result = code_->constants().size(); - code_->constants_.push_back(value); - return result; - } - - Context* ctx_; - Code* code_; - JSStringToIndexMap jsstring_to_index_map_; - JSDoubleToIndexMap double_to_index_map_; - uint32_t undefined_index_; - uint32_t null_index_; - uint32_t true_index_; - uint32_t false_index_; - uint32_t empty_index_; - }; - friend class ThunkPool; friend class ArraySite; friend class CallSite; diff --git a/iv/lv5/railgun/constant_pool.h b/iv/lv5/railgun/constant_pool.h new file mode 100644 index 00000000..cfc6f245 --- /dev/null +++ b/iv/lv5/railgun/constant_pool.h @@ -0,0 +1,179 @@ +#ifndef IV_LV5_RAILGUN_CONSTANT_POOL_H_ +#define IV_LV5_RAILGUN_CONSTANT_POOL_H_ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +namespace iv { +namespace lv5 { +namespace railgun { + +class ConstantPool { + // Bytecode register size is very limited. + // So probably, constant register may be overflown sometimes. + // When constant register is overflown, we can use LOAD_CONST instead of + // constant register. + public: + static const uint32_t kEmpty = UINT32_MAX; + + typedef std::unordered_map JSStringToIndexMap; + typedef std::unordered_map< + double, + int32_t, + std::hash, JSDoubleEquals> JSDoubleToIndexMap; + + ConstantPool(Context* ctx) + : ctx_(ctx), + code_(NULL), + jsstring_to_index_map_(), + double_to_index_map_(), + undefined_index_(), + null_index_(), + true_index_(), + false_index_(), + empty_index_() { + } + + void Init(Code* code) { + code_ = code; + jsstring_to_index_map_.clear(); + double_to_index_map_.clear(); + undefined_index_ = kEmpty; + null_index_ = kEmpty; + true_index_ = kEmpty; + false_index_ = kEmpty; + empty_index_ = kEmpty; + } + + uint32_t undefined_index() { + if (undefined_index_ != kEmpty) { + return undefined_index_; + } + undefined_index_ = AddConstant(JSUndefined); + return undefined_index_; + } + + uint32_t null_index() { + if (null_index_ != kEmpty) { + return null_index_; + } + null_index_ = AddConstant(JSNull); + return null_index_; + } + + uint32_t true_index() { + if (true_index_ != kEmpty) { + return true_index_; + } + true_index_ = AddConstant(JSTrue); + return true_index_; + } + + uint32_t false_index() { + if (false_index_ != kEmpty) { + return false_index_; + } + false_index_ = AddConstant(JSFalse); + return false_index_; + } + + uint32_t empty_index() { + if (empty_index_ != kEmpty) { + return empty_index_; + } + empty_index_ = AddConstant(JSEmpty); + return empty_index_; + } + + uint32_t string_index(const core::UString& str) { + const JSStringToIndexMap::const_iterator it = + jsstring_to_index_map_.find(str); + + if (it != jsstring_to_index_map_.end()) { + // duplicate constant + return it->second; + } + + // new constant value + Error::Dummy dummy; + const uint32_t index = AddConstant( + JSString::New( + ctx_, + str.begin(), + str.end(), + core::character::IsASCII(str.begin(), str.end()), &dummy)); + jsstring_to_index_map_.insert(std::make_pair(str, index)); + return index; + } + + uint32_t string_index(const StringLiteral* str) { + return string_index(core::ToUString(str->value())); + } + + uint32_t string_index(const core::StringPiece& str) { + return string_index(core::ToUString(str)); + } + + uint32_t string_index(const core::UStringPiece& str) { + return string_index(core::UString(str)); + } + + uint32_t number_index(double val) { + const JSDoubleToIndexMap::const_iterator it = + double_to_index_map_.find(val); + + if (it != double_to_index_map_.end()) { + // duplicate constant pool + return it->second; + } + + // new constant value + const uint32_t index = AddConstant(val); + double_to_index_map_.insert(std::make_pair(val, index)); + return index; + } + + uint32_t Lookup(JSVal constant) { + if (constant.IsString()) { + return string_index(constant.string()->GetUString()); + } else if (constant.IsNumber()) { + return number_index(constant.number()); + } else if (constant.IsUndefined()) { + return undefined_index(); + } else if (constant.IsNull()) { + return null_index(); + } else if (constant.IsBoolean()) { + return (constant.boolean()) ? true_index() : false_index(); + } else if (constant.IsEmpty()) { + return empty_index(); + } + UNREACHABLE(); + return 0; // makes compiler happy + } + + private: + uint32_t AddConstant(JSVal value) { + const uint32_t result = code_->constants().size(); + code_->constants_.push_back(value); + return result; + } + + Context* ctx_; + Code* code_; + JSStringToIndexMap jsstring_to_index_map_; + JSDoubleToIndexMap double_to_index_map_; + uint32_t undefined_index_; + uint32_t null_index_; + uint32_t true_index_; + uint32_t false_index_; + uint32_t empty_index_; +}; + +} } } // namespace iv::lv5::railgun +#endif // IV_LV5_RAILGUN_CONSTANT_POOL_H_ diff --git a/iv/lv5/railgun/fwd.h b/iv/lv5/railgun/fwd.h index 43c960e0..9803a036 100644 --- a/iv/lv5/railgun/fwd.h +++ b/iv/lv5/railgun/fwd.h @@ -19,6 +19,7 @@ class WithScope; class CatchScope; class Compiler; +class ConstantPool; class Context; class NativeIterator;