Commit 2234c4d5 authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

[csa] Add scoped exception handler support for non-PLabels

In the process, move the rest of the implementation PLabels into the
CodeAssembler for consistency.

Change-Id: I56872d9fc756db066f0d13d87aeb55ec04de2495
Reviewed-on: https://chromium-review.googlesource.com/c/1329687
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57474}
parent 019494b3
...@@ -2539,7 +2539,6 @@ v8_source_set("v8_base") { ...@@ -2539,7 +2539,6 @@ v8_source_set("v8_base") {
"src/third_party/utf8-decoder/utf8-decoder.h", "src/third_party/utf8-decoder/utf8-decoder.h",
"src/thread-id.cc", "src/thread-id.cc",
"src/thread-id.h", "src/thread-id.h",
"src/torque-assembler.h",
"src/tracing/trace-event.cc", "src/tracing/trace-event.cc",
"src/tracing/trace-event.h", "src/tracing/trace-event.h",
"src/tracing/traced-value.cc", "src/tracing/traced-value.cc",
......
...@@ -966,10 +966,10 @@ TNode<BoolT> CodeStubAssembler::WordIsWordAligned(SloppyTNode<WordT> word) { ...@@ -966,10 +966,10 @@ TNode<BoolT> CodeStubAssembler::WordIsWordAligned(SloppyTNode<WordT> word) {
void CodeStubAssembler::Bind(Label* label, AssemblerDebugInfo debug_info) { void CodeStubAssembler::Bind(Label* label, AssemblerDebugInfo debug_info) {
CodeAssembler::Bind(label, debug_info); CodeAssembler::Bind(label, debug_info);
} }
#else
void CodeStubAssembler::Bind(Label* label) { CodeAssembler::Bind(label); }
#endif // DEBUG #endif // DEBUG
void CodeStubAssembler::Bind(Label* label) { CodeAssembler::Bind(label); }
TNode<Float64T> CodeStubAssembler::LoadDoubleWithHoleCheck( TNode<Float64T> CodeStubAssembler::LoadDoubleWithHoleCheck(
TNode<FixedDoubleArray> array, TNode<Smi> index, Label* if_hole) { TNode<FixedDoubleArray> array, TNode<Smi> index, Label* if_hole) {
return LoadFixedDoubleArrayElement(array, index, MachineType::Float64(), 0, return LoadFixedDoubleArrayElement(array, index, MachineType::Float64(), 0,
......
...@@ -776,9 +776,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -776,9 +776,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
#if DEBUG #if DEBUG
void Bind(Label* label, AssemblerDebugInfo debug_info); void Bind(Label* label, AssemblerDebugInfo debug_info);
#else
void Bind(Label* label);
#endif // DEBUG #endif // DEBUG
void Bind(Label* label);
template <class... T>
void Bind(compiler::CodeAssemblerParameterizedLabel<T...>* label,
TNode<T>*... phis) {
CodeAssembler::Bind(label, phis...);
}
void BranchIfSmiEqual(TNode<Smi> a, TNode<Smi> b, Label* if_true, void BranchIfSmiEqual(TNode<Smi> a, TNode<Smi> b, Label* if_true,
Label* if_false) { Label* if_false) {
......
...@@ -98,9 +98,9 @@ CodeAssembler::~CodeAssembler() = default; ...@@ -98,9 +98,9 @@ CodeAssembler::~CodeAssembler() = default;
void CodeAssemblerState::PrintCurrentBlock(std::ostream& os) { void CodeAssemblerState::PrintCurrentBlock(std::ostream& os) {
raw_assembler_->PrintCurrentBlock(os); raw_assembler_->PrintCurrentBlock(os);
} }
#endif
bool CodeAssemblerState::InsideBlock() { return raw_assembler_->InsideBlock(); } bool CodeAssemblerState::InsideBlock() { return raw_assembler_->InsideBlock(); }
#endif
void CodeAssemblerState::SetInitialDebugInformation(const char* msg, void CodeAssemblerState::SetInitialDebugInformation(const char* msg,
const char* file, const char* file,
...@@ -1866,6 +1866,51 @@ void CodeAssemblerState::PopExceptionHandler() { ...@@ -1866,6 +1866,51 @@ void CodeAssemblerState::PopExceptionHandler() {
exception_handler_labels_.pop_back(); exception_handler_labels_.pop_back();
} }
CodeAssemblerScopedExceptionHandler::CodeAssemblerScopedExceptionHandler(
CodeAssembler* assembler, CodeAssemblerExceptionHandlerLabel* label)
: has_handler_(label != nullptr),
assembler_(assembler),
compatibility_label_(nullptr),
exception_(nullptr) {
if (has_handler_) {
assembler_->state()->PushExceptionHandler(label);
}
}
CodeAssemblerScopedExceptionHandler::CodeAssemblerScopedExceptionHandler(
CodeAssembler* assembler, CodeAssemblerLabel* label,
TypedCodeAssemblerVariable<Object>* exception)
: has_handler_(label != nullptr),
assembler_(assembler),
compatibility_label_(label),
exception_(exception) {
if (has_handler_) {
label_ = base::make_unique<CodeAssemblerExceptionHandlerLabel>(
assembler, CodeAssemblerLabel::kDeferred);
assembler_->state()->PushExceptionHandler(label_.get());
}
}
CodeAssemblerScopedExceptionHandler::~CodeAssemblerScopedExceptionHandler() {
if (has_handler_) {
assembler_->state()->PopExceptionHandler();
}
if (label_ && label_->is_used()) {
CodeAssembler::Label skip(assembler_);
bool inside_block = assembler_->state()->InsideBlock();
if (inside_block) {
assembler_->Goto(&skip);
}
TNode<Object> e;
assembler_->Bind(label_.get(), &e);
*exception_ = e;
assembler_->Goto(compatibility_label_);
if (inside_block) {
assembler_->Bind(&skip);
}
}
}
} // namespace compiler } // namespace compiler
Address CheckObjectType(Object* value, Address raw_type, String* location) { Address CheckObjectType(Object* value, Address raw_type, String* location) {
......
...@@ -60,7 +60,6 @@ class PromiseFulfillReactionJobTask; ...@@ -60,7 +60,6 @@ class PromiseFulfillReactionJobTask;
class PromiseReaction; class PromiseReaction;
class PromiseReactionJobTask; class PromiseReactionJobTask;
class PromiseRejectReactionJobTask; class PromiseRejectReactionJobTask;
class TorqueAssembler;
class WeakFactoryCleanupJobTask; class WeakFactoryCleanupJobTask;
class Zone; class Zone;
...@@ -830,11 +829,27 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -830,11 +829,27 @@ class V8_EXPORT_PRIVATE CodeAssembler {
void Branch(SloppyTNode<IntegralT> condition, Label* true_label, void Branch(SloppyTNode<IntegralT> condition, Label* true_label,
Label* false_label); Label* false_label);
template <class... Ts> template <class T>
using PLabel = compiler::CodeAssemblerParameterizedLabel<Ts...>; TNode<T> Uninitialized() {
return {};
}
template <class... T>
void Bind(CodeAssemblerParameterizedLabel<T...>* label, TNode<T>*... phis) {
Bind(label->plain_label());
label->CreatePhis(phis...);
}
template <class... T, class... Args>
void Branch(TNode<BoolT> condition,
CodeAssemblerParameterizedLabel<T...>* if_true,
CodeAssemblerParameterizedLabel<T...>* if_false, Args... args) {
if_true->AddInputs(args...);
if_false->AddInputs(args...);
Branch(condition, if_true->plain_label(), if_false->plain_label());
}
template <class... T, class... Args> template <class... T, class... Args>
void Goto(PLabel<T...>* label, Args... args) { void Goto(CodeAssemblerParameterizedLabel<T...>* label, Args... args) {
label->AddInputs(args...); label->AddInputs(args...);
Goto(label->plain_label()); Goto(label->plain_label());
} }
...@@ -1530,7 +1545,6 @@ class CodeAssemblerParameterizedLabel ...@@ -1530,7 +1545,6 @@ class CodeAssemblerParameterizedLabel
: CodeAssemblerParameterizedLabelBase(assembler, kArity, type) {} : CodeAssemblerParameterizedLabelBase(assembler, kArity, type) {}
private: private:
friend class internal::TorqueAssembler;
friend class CodeAssembler; friend class CodeAssembler;
void AddInputs(TNode<Types>... inputs) { void AddInputs(TNode<Types>... inputs) {
...@@ -1578,8 +1592,8 @@ class V8_EXPORT_PRIVATE CodeAssemblerState { ...@@ -1578,8 +1592,8 @@ class V8_EXPORT_PRIVATE CodeAssemblerState {
#if DEBUG #if DEBUG
void PrintCurrentBlock(std::ostream& os); void PrintCurrentBlock(std::ostream& os);
bool InsideBlock();
#endif // DEBUG #endif // DEBUG
bool InsideBlock();
void SetInitialDebugInformation(const char* msg, const char* file, int line); void SetInitialDebugInformation(const char* msg, const char* file, int line);
private: private:
...@@ -1618,18 +1632,23 @@ class V8_EXPORT_PRIVATE CodeAssemblerState { ...@@ -1618,18 +1632,23 @@ class V8_EXPORT_PRIVATE CodeAssemblerState {
class CodeAssemblerScopedExceptionHandler { class CodeAssemblerScopedExceptionHandler {
public: public:
CodeAssemblerScopedExceptionHandler(CodeAssembler* assembler, CodeAssemblerScopedExceptionHandler(
CodeAssemblerExceptionHandlerLabel* label) CodeAssembler* assembler, CodeAssemblerExceptionHandlerLabel* label);
: assembler_(assembler) {
assembler_->state()->PushExceptionHandler(label);
}
~CodeAssemblerScopedExceptionHandler() { // Use this constructor for compatability/ports of old CSA code only. New code
assembler_->state()->PopExceptionHandler(); // should use the CodeAssemblerExceptionHandlerLabel version.
} CodeAssemblerScopedExceptionHandler(
CodeAssembler* assembler, CodeAssemblerLabel* label,
TypedCodeAssemblerVariable<Object>* exception);
~CodeAssemblerScopedExceptionHandler();
private: private:
bool has_handler_;
CodeAssembler* assembler_; CodeAssembler* assembler_;
CodeAssemblerLabel* compatibility_label_;
std::unique_ptr<CodeAssemblerExceptionHandlerLabel> label_;
TypedCodeAssemblerVariable<Object>* exception_;
}; };
} // namespace compiler } // namespace compiler
......
...@@ -478,14 +478,14 @@ void RawMachineAssembler::PrintCurrentBlock(std::ostream& os) { ...@@ -478,14 +478,14 @@ void RawMachineAssembler::PrintCurrentBlock(std::ostream& os) {
os << CurrentBlock(); os << CurrentBlock();
} }
bool RawMachineAssembler::InsideBlock() { return current_block_ != nullptr; }
void RawMachineAssembler::SetInitialDebugInformation( void RawMachineAssembler::SetInitialDebugInformation(
AssemblerDebugInfo debug_info) { AssemblerDebugInfo debug_info) {
CurrentBlock()->set_debug_info(debug_info); CurrentBlock()->set_debug_info(debug_info);
} }
#endif // DEBUG #endif // DEBUG
bool RawMachineAssembler::InsideBlock() { return current_block_ != nullptr; }
BasicBlock* RawMachineAssembler::CurrentBlock() { BasicBlock* RawMachineAssembler::CurrentBlock() {
DCHECK(current_block_); DCHECK(current_block_);
return current_block_; return current_block_;
......
...@@ -938,8 +938,8 @@ class V8_EXPORT_PRIVATE RawMachineAssembler { ...@@ -938,8 +938,8 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
void Bind(RawMachineLabel* label, AssemblerDebugInfo info); void Bind(RawMachineLabel* label, AssemblerDebugInfo info);
void SetInitialDebugInformation(AssemblerDebugInfo info); void SetInitialDebugInformation(AssemblerDebugInfo info);
void PrintCurrentBlock(std::ostream& os); void PrintCurrentBlock(std::ostream& os);
bool InsideBlock();
#endif // DEBUG #endif // DEBUG
bool InsideBlock();
// Add success / exception successor blocks and ends the current block ending // Add success / exception successor blocks and ends the current block ending
// in a potentially throwing call node. // in a potentially throwing call node.
......
// Copyright 2018 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.
#ifndef V8_TORQUE_ASSEMBLER_H_
#define V8_TORQUE_ASSEMBLER_H_
#include <deque>
#include <vector>
#include "src/code-stub-assembler.h"
#include "src/base/optional.h"
namespace v8 {
namespace internal {
class TorqueAssembler : public CodeStubAssembler {
public:
using CodeStubAssembler::CodeStubAssembler;
protected:
template <class... Ts>
using PLabel = compiler::CodeAssemblerParameterizedLabel<Ts...>;
template <class T>
TNode<T> Uninitialized() {
return {};
}
template <class... T>
void Bind(PLabel<T...>* label, TNode<T>*... phis) {
Bind(label->plain_label());
label->CreatePhis(phis...);
}
void Bind(Label* label) { CodeAssembler::Bind(label); }
using CodeStubAssembler::Bind;
template <class... T, class... Args>
void Branch(TNode<BoolT> condition, PLabel<T...>* if_true,
PLabel<T...>* if_false, Args... args) {
if_true->AddInputs(args...);
if_false->AddInputs(args...);
CodeStubAssembler::Branch(condition, if_true->plain_label(),
if_false->plain_label());
}
using CodeStubAssembler::Branch;
};
} // namespace internal
} // namespace v8
#endif // V8_TORQUE_ASSEMBLER_H_
...@@ -75,6 +75,8 @@ void ImplementationVisitor::BeginNamespaceFile(Namespace* nspace) { ...@@ -75,6 +75,8 @@ void ImplementationVisitor::BeginNamespaceFile(Namespace* nspace) {
<< "using Node = compiler::Node;\n" << "using Node = compiler::Node;\n"
<< "using CatchLabel = compiler::CodeAssemblerExceptionHandlerLabel;\n" << "using CatchLabel = compiler::CodeAssemblerExceptionHandlerLabel;\n"
<< "using ScopedCatch = compiler::CodeAssemblerScopedExceptionHandler;\n" << "using ScopedCatch = compiler::CodeAssemblerScopedExceptionHandler;\n"
<< "template <class... Ts>\n"
<< "using PLabel = compiler::CodeAssemblerParameterizedLabel<Ts...>;\n"
<< "\n"; << "\n";
std::string upper_name(nspace->name()); std::string upper_name(nspace->name());
...@@ -84,7 +86,7 @@ void ImplementationVisitor::BeginNamespaceFile(Namespace* nspace) { ...@@ -84,7 +86,7 @@ void ImplementationVisitor::BeginNamespaceFile(Namespace* nspace) {
std::string("V8_TORQUE_") + upper_name + "_FROM_DSL_BASE_H__"; std::string("V8_TORQUE_") + upper_name + "_FROM_DSL_BASE_H__";
header << "#ifndef " << headerDefine << "\n"; header << "#ifndef " << headerDefine << "\n";
header << "#define " << headerDefine << "\n\n"; header << "#define " << headerDefine << "\n\n";
header << "#include \"src/torque-assembler.h\""; header << "#include \"src/code-stub-assembler.h\"";
header << "\n\n "; header << "\n\n ";
header << "namespace v8 {\n" header << "namespace v8 {\n"
...@@ -92,11 +94,11 @@ void ImplementationVisitor::BeginNamespaceFile(Namespace* nspace) { ...@@ -92,11 +94,11 @@ void ImplementationVisitor::BeginNamespaceFile(Namespace* nspace) {
<< "\n"; << "\n";
header << "class " << nspace->ExternalName() header << "class " << nspace->ExternalName()
<< ": public TorqueAssembler {\n"; << ": public CodeStubAssembler {\n";
header << " public:\n"; header << " public:\n";
header header << " explicit " << nspace->ExternalName()
<< " explicit " << nspace->ExternalName() << "(compiler::CodeAssemblerState* state) : CodeStubAssembler(state) "
<< "(compiler::CodeAssemblerState* state) : TorqueAssembler(state) {}\n"; "{}\n";
header << "\n"; header << "\n";
header << " using Node = compiler::Node;\n"; header << " using Node = compiler::Node;\n";
......
...@@ -560,6 +560,28 @@ TEST(GotoIfExceptionMultiple) { ...@@ -560,6 +560,28 @@ TEST(GotoIfExceptionMultiple) {
CHECK(constructor->SameValue(*isolate->type_error_function())); CHECK(constructor->SameValue(*isolate->type_error_function()));
} }
TEST(ExceptionHandler) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 0;
CodeAssemblerTester asm_tester(isolate, kNumParams);
CodeAssembler m(asm_tester.state());
CodeAssembler::TVariable<Object> var(m.SmiConstant(0), &m);
Label exception(&m, {&var}, Label::kDeferred);
{
CodeAssemblerScopedExceptionHandler handler(&m, &exception, &var);
Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
m.CallRuntime(Runtime::kThrow, context, m.SmiConstant(2));
}
m.Return(m.SmiConstant(1));
m.Bind(&exception);
m.Return(var.value());
FunctionTester ft(asm_tester.GenerateCode(), kNumParams);
CHECK_EQ(2, ft.CallChecked<Smi>()->value());
}
} // namespace compiler } // namespace compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment