| Index: src/arm64/lithium-arm64.h
|
| diff --git a/src/arm64/lithium-arm64.h b/src/arm64/lithium-arm64.h
|
| index fc6e667c6061295788eea765721d57f7616cff96..339e3a623234792bd9bc3ad2c93da5fcd50ac2fb 100644
|
| --- a/src/arm64/lithium-arm64.h
|
| +++ b/src/arm64/lithium-arm64.h
|
| @@ -5,6 +5,7 @@
|
| #ifndef V8_ARM64_LITHIUM_ARM64_H_
|
| #define V8_ARM64_LITHIUM_ARM64_H_
|
|
|
| +#include "heap.h"
|
| #include "hydrogen.h"
|
| #include "lithium-allocator.h"
|
| #include "lithium.h"
|
| @@ -231,6 +232,10 @@ class LInstruction : public ZoneObject {
|
|
|
| virtual bool IsControl() const { return false; }
|
|
|
| + // Indicates wether it is more efficient to regenerate the value rather than
|
| + // spill and reload it.
|
| + virtual bool PreferRegenerateToSpill() const { return false; }
|
| +
|
| void set_environment(LEnvironment* env) { environment_ = env; }
|
| LEnvironment* environment() const { return environment_; }
|
| bool HasEnvironment() const { return environment_ != NULL; }
|
| @@ -1198,6 +1203,8 @@ class LConstantD V8_FINAL : public LTemplateInstruction<1, 0, 0> {
|
| DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
|
| DECLARE_HYDROGEN_ACCESSOR(Constant)
|
|
|
| + virtual bool PreferRegenerateToSpill() const V8_OVERRIDE { return true; }
|
| +
|
| double value() const { return hydrogen()->DoubleValue(); }
|
| };
|
|
|
| @@ -1207,6 +1214,8 @@ class LConstantE V8_FINAL : public LTemplateInstruction<1, 0, 0> {
|
| DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
|
| DECLARE_HYDROGEN_ACCESSOR(Constant)
|
|
|
| + virtual bool PreferRegenerateToSpill() const V8_OVERRIDE { return true; }
|
| +
|
| ExternalReference value() const {
|
| return hydrogen()->ExternalReferenceValue();
|
| }
|
| @@ -1218,6 +1227,8 @@ class LConstantI V8_FINAL : public LTemplateInstruction<1, 0, 0> {
|
| DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
|
| DECLARE_HYDROGEN_ACCESSOR(Constant)
|
|
|
| + virtual bool PreferRegenerateToSpill() const V8_OVERRIDE { return true; }
|
| +
|
| int32_t value() const { return hydrogen()->Integer32Value(); }
|
| };
|
|
|
| @@ -1227,6 +1238,8 @@ class LConstantS V8_FINAL : public LTemplateInstruction<1, 0, 0> {
|
| DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
|
| DECLARE_HYDROGEN_ACCESSOR(Constant)
|
|
|
| + virtual bool PreferRegenerateToSpill() const V8_OVERRIDE { return true; }
|
| +
|
| Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
|
| };
|
|
|
| @@ -3018,37 +3031,46 @@ class ConstantCache {
|
|
|
| class ConstantCacheLevel {
|
| public:
|
| - void Cache(HConstant* constant) { cached_constants_.insert(constant); }
|
| - bool IsCached(HConstant* constant) {
|
| - return cached_constants_.find(constant) != cached_constants_.end();
|
| + void Cache(HConstant* constant, LInstruction* instr) {
|
| + cached_constants_[constant] = instr;
|
| + }
|
| + LInstruction* CachedLInstructionFor(HConstant* constant) {
|
| + std::map<HConstant*, LInstruction*>::iterator it;
|
| + it = cached_constants_.find(constant);
|
| + return (it == cached_constants_.end()) ? NULL : it->second;
|
| }
|
|
|
| private:
|
| - std::set<HConstant*> cached_constants_;
|
| + std::map<HConstant*, LInstruction*> cached_constants_;
|
| };
|
|
|
| void Clear() { cache_levels_.clear(); }
|
|
|
| - void Cache(HConstant* constant, HBasicBlock* block) {
|
| - cache_levels_[block].Cache(constant);
|
| + void Cache(HConstant* constant, LInstruction* instr, HBasicBlock* block) {
|
| + cache_levels_[block].Cache(constant, instr);
|
| }
|
|
|
| - bool IsCached(HConstant* constant, HBasicBlock* block) {
|
| + LInstruction* CachedLInstructionFor(HConstant* constant, HBasicBlock* block) {
|
| HBasicBlock* base_block = block;
|
| std::map<HBasicBlock*, ConstantCacheLevel>::iterator it;
|
| + LInstruction* instr;
|
| + // Look for the constant in the specified block or the dominator blocks.
|
| while (block != NULL) {
|
| it = cache_levels_.find(block);
|
| - if (it != cache_levels_.end() && it->second.IsCached(constant)) {
|
| - if (base_block != block) {
|
| - // Avoid traversing the dominator blocks multiple times for the same
|
| - // constant.
|
| - cache_levels_[block].Cache(constant);
|
| + if (it != cache_levels_.end()) {
|
| + instr = it->second.CachedLInstructionFor(constant);
|
| + if (instr != NULL) {
|
| + if (base_block != block) {
|
| + // Avoid traversing the dominator blocks multiple times for the same
|
| + // constant.
|
| + cache_levels_[block].Cache(constant, instr);
|
| + }
|
| + return instr;
|
| }
|
| - return true;
|
| }
|
| block = block->dominator();
|
| }
|
| - return false;
|
| + return NULL;
|
| }
|
|
|
| private:
|
| @@ -3099,11 +3121,12 @@ class LChunkBuilder V8_FINAL : public LChunkBuilderBase {
|
|
|
| static bool HasMagicNumberForDivision(int32_t divisor);
|
|
|
| - bool IsCachedConstant(HConstant* constant, HBasicBlock* block) {
|
| - return constant_cache_.IsCached(constant, block);
|
| + LInstruction* CachedLInstructionFor(HConstant* constant, HBasicBlock* block) {
|
| + return constant_cache_.CachedLInstructionFor(constant, block);
|
| }
|
| - void CacheConstant(HConstant* constant, HBasicBlock* block) {
|
| - constant_cache_.Cache(constant, block);
|
| + void CacheConstant(HConstant* constant, LInstruction* instr,
|
| + HBasicBlock* block) {
|
| + constant_cache_.Cache(constant, instr, block);
|
| }
|
|
|
| private:
|
|
|