7d3c9bce1f
The slow-path emitted by the memory optimizer now checks if large object allocations were allowed before going ahead and allocating a large object. This is important because manual allocation folding in CSA must not be performed on a large object. Bug: v8:9388 Change-Id: I74b840c9c9276bd17611842e0eae7b0e58b142d2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1675960 Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#62605}
206 lines
7.3 KiB
C++
206 lines
7.3 KiB
C++
// Copyright 2014 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "src/compiler/js-graph.h"
|
|
|
|
#include "src/codegen/code-factory.h"
|
|
#include "src/compiler/node-properties.h"
|
|
#include "src/compiler/typer.h"
|
|
#include "src/objects/objects-inl.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
namespace compiler {
|
|
|
|
#define GET_CACHED_FIELD(ptr, expr) (*(ptr)) ? *(ptr) : (*(ptr) = (expr))
|
|
|
|
#define DEFINE_GETTER(name, expr) \
|
|
Node* JSGraph::name() { return GET_CACHED_FIELD(&name##_, expr); }
|
|
|
|
Node* JSGraph::CEntryStubConstant(int result_size, SaveFPRegsMode save_doubles,
|
|
ArgvMode argv_mode, bool builtin_exit_frame) {
|
|
if (save_doubles == kDontSaveFPRegs && argv_mode == kArgvOnStack) {
|
|
DCHECK(result_size >= 1 && result_size <= 3);
|
|
if (!builtin_exit_frame) {
|
|
Node** ptr = nullptr;
|
|
if (result_size == 1) {
|
|
ptr = &CEntryStub1Constant_;
|
|
} else if (result_size == 2) {
|
|
ptr = &CEntryStub2Constant_;
|
|
} else {
|
|
DCHECK_EQ(3, result_size);
|
|
ptr = &CEntryStub3Constant_;
|
|
}
|
|
return GET_CACHED_FIELD(ptr, HeapConstant(CodeFactory::CEntry(
|
|
isolate(), result_size, save_doubles,
|
|
argv_mode, builtin_exit_frame)));
|
|
}
|
|
Node** ptr = builtin_exit_frame ? &CEntryStub1WithBuiltinExitFrameConstant_
|
|
: &CEntryStub1Constant_;
|
|
return GET_CACHED_FIELD(ptr, HeapConstant(CodeFactory::CEntry(
|
|
isolate(), result_size, save_doubles,
|
|
argv_mode, builtin_exit_frame)));
|
|
}
|
|
return HeapConstant(CodeFactory::CEntry(isolate(), result_size, save_doubles,
|
|
argv_mode, builtin_exit_frame));
|
|
}
|
|
|
|
Node* JSGraph::Constant(Handle<Object> value) {
|
|
// Dereference the handle to determine if a number constant or other
|
|
// canonicalized node can be used.
|
|
if (value->IsNumber()) {
|
|
return Constant(value->Number());
|
|
} else if (value->IsUndefined(isolate())) {
|
|
return UndefinedConstant();
|
|
} else if (value->IsTrue(isolate())) {
|
|
return TrueConstant();
|
|
} else if (value->IsFalse(isolate())) {
|
|
return FalseConstant();
|
|
} else if (value->IsNull(isolate())) {
|
|
return NullConstant();
|
|
} else if (value->IsTheHole(isolate())) {
|
|
return TheHoleConstant();
|
|
} else {
|
|
return HeapConstant(Handle<HeapObject>::cast(value));
|
|
}
|
|
}
|
|
|
|
Node* JSGraph::Constant(const ObjectRef& ref) {
|
|
if (ref.IsSmi()) return Constant(ref.AsSmi());
|
|
OddballType oddball_type =
|
|
ref.AsHeapObject().GetHeapObjectType().oddball_type();
|
|
if (ref.IsHeapNumber()) {
|
|
return Constant(ref.AsHeapNumber().value());
|
|
} else if (oddball_type == OddballType::kUndefined) {
|
|
DCHECK(ref.object().equals(isolate()->factory()->undefined_value()));
|
|
return UndefinedConstant();
|
|
} else if (oddball_type == OddballType::kNull) {
|
|
DCHECK(ref.object().equals(isolate()->factory()->null_value()));
|
|
return NullConstant();
|
|
} else if (oddball_type == OddballType::kHole) {
|
|
DCHECK(ref.object().equals(isolate()->factory()->the_hole_value()));
|
|
return TheHoleConstant();
|
|
} else if (oddball_type == OddballType::kBoolean) {
|
|
if (ref.object().equals(isolate()->factory()->true_value())) {
|
|
return TrueConstant();
|
|
} else {
|
|
DCHECK(ref.object().equals(isolate()->factory()->false_value()));
|
|
return FalseConstant();
|
|
}
|
|
} else {
|
|
return HeapConstant(ref.AsHeapObject().object());
|
|
}
|
|
}
|
|
|
|
Node* JSGraph::Constant(double value) {
|
|
if (bit_cast<int64_t>(value) == bit_cast<int64_t>(0.0)) return ZeroConstant();
|
|
if (bit_cast<int64_t>(value) == bit_cast<int64_t>(1.0)) return OneConstant();
|
|
return NumberConstant(value);
|
|
}
|
|
|
|
Node* JSGraph::NumberConstant(double value) {
|
|
Node** loc = cache_.FindNumberConstant(value);
|
|
if (*loc == nullptr) {
|
|
*loc = graph()->NewNode(common()->NumberConstant(value));
|
|
}
|
|
return *loc;
|
|
}
|
|
|
|
Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
|
|
Node** loc = cache_.FindHeapConstant(value);
|
|
if (*loc == nullptr) {
|
|
*loc = graph()->NewNode(common()->HeapConstant(value));
|
|
}
|
|
return *loc;
|
|
}
|
|
|
|
void JSGraph::GetCachedNodes(NodeVector* nodes) {
|
|
cache_.GetCachedNodes(nodes);
|
|
#define DO_CACHED_FIELD(name) \
|
|
if (name##_) nodes->push_back(name##_);
|
|
|
|
CACHED_GLOBAL_LIST(DO_CACHED_FIELD)
|
|
CACHED_CENTRY_LIST(DO_CACHED_FIELD)
|
|
#undef DO_CACHED_FIELD
|
|
}
|
|
|
|
DEFINE_GETTER(AllocateInYoungGenerationStubConstant,
|
|
HeapConstant(BUILTIN_CODE(isolate(), AllocateInYoungGeneration)))
|
|
|
|
DEFINE_GETTER(AllocateRegularInYoungGenerationStubConstant,
|
|
HeapConstant(BUILTIN_CODE(isolate(),
|
|
AllocateRegularInYoungGeneration)))
|
|
|
|
DEFINE_GETTER(AllocateInOldGenerationStubConstant,
|
|
HeapConstant(BUILTIN_CODE(isolate(), AllocateInOldGeneration)))
|
|
|
|
DEFINE_GETTER(AllocateRegularInOldGenerationStubConstant,
|
|
HeapConstant(BUILTIN_CODE(isolate(),
|
|
AllocateRegularInOldGeneration)))
|
|
|
|
DEFINE_GETTER(ArrayConstructorStubConstant,
|
|
HeapConstant(BUILTIN_CODE(isolate(), ArrayConstructorImpl)))
|
|
|
|
DEFINE_GETTER(BigIntMapConstant, HeapConstant(factory()->bigint_map()))
|
|
|
|
DEFINE_GETTER(BooleanMapConstant, HeapConstant(factory()->boolean_map()))
|
|
|
|
DEFINE_GETTER(ToNumberBuiltinConstant,
|
|
HeapConstant(BUILTIN_CODE(isolate(), ToNumber)))
|
|
|
|
DEFINE_GETTER(EmptyFixedArrayConstant,
|
|
HeapConstant(factory()->empty_fixed_array()))
|
|
|
|
DEFINE_GETTER(EmptyStringConstant, HeapConstant(factory()->empty_string()))
|
|
|
|
DEFINE_GETTER(FixedArrayMapConstant, HeapConstant(factory()->fixed_array_map()))
|
|
|
|
DEFINE_GETTER(PropertyArrayMapConstant,
|
|
HeapConstant(factory()->property_array_map()))
|
|
|
|
DEFINE_GETTER(FixedDoubleArrayMapConstant,
|
|
HeapConstant(factory()->fixed_double_array_map()))
|
|
|
|
DEFINE_GETTER(HeapNumberMapConstant, HeapConstant(factory()->heap_number_map()))
|
|
|
|
DEFINE_GETTER(OptimizedOutConstant, HeapConstant(factory()->optimized_out()))
|
|
|
|
DEFINE_GETTER(StaleRegisterConstant, HeapConstant(factory()->stale_register()))
|
|
|
|
DEFINE_GETTER(UndefinedConstant, HeapConstant(factory()->undefined_value()))
|
|
|
|
DEFINE_GETTER(TheHoleConstant, HeapConstant(factory()->the_hole_value()))
|
|
|
|
DEFINE_GETTER(TrueConstant, HeapConstant(factory()->true_value()))
|
|
|
|
DEFINE_GETTER(FalseConstant, HeapConstant(factory()->false_value()))
|
|
|
|
DEFINE_GETTER(NullConstant, HeapConstant(factory()->null_value()))
|
|
|
|
DEFINE_GETTER(ZeroConstant, NumberConstant(0.0))
|
|
|
|
DEFINE_GETTER(OneConstant, NumberConstant(1.0))
|
|
|
|
DEFINE_GETTER(MinusOneConstant, NumberConstant(-1.0))
|
|
|
|
DEFINE_GETTER(NaNConstant,
|
|
NumberConstant(std::numeric_limits<double>::quiet_NaN()))
|
|
|
|
DEFINE_GETTER(EmptyStateValues,
|
|
graph()->NewNode(common()->StateValues(0,
|
|
SparseInputMask::Dense())))
|
|
|
|
DEFINE_GETTER(SingleDeadTypedStateValues,
|
|
graph()->NewNode(common()->TypedStateValues(
|
|
new (graph()->zone()->New(sizeof(ZoneVector<MachineType>)))
|
|
ZoneVector<MachineType>(0, graph()->zone()),
|
|
SparseInputMask(SparseInputMask::kEndMarker << 1))))
|
|
|
|
#undef DEFINE_GETTER
|
|
#undef GET_CACHED_FIELD
|
|
|
|
} // namespace compiler
|
|
} // namespace internal
|
|
} // namespace v8
|