Revert "[regexp] Protect against reentrant RegExpStack use"
This reverts commit e2408c2521
.
Reason for revert: https://ci.chromium.org/p/v8/builders/ci/V8%20Mac64/36733?1
Original change's description:
> [regexp] Protect against reentrant RegExpStack use
>
> Irregexp, and in particular the RegExpStack, are not reentrant.
> Explicitly guard against reentrancy.
>
> Bug: chromium:1125934
> Change-Id: I0fc295f6986a89221982e6a2ccefed46193974f6
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2460820
> Commit-Queue: Yang Guo <yangguo@chromium.org>
> Auto-Submit: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Yang Guo <yangguo@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#70436}
TBR=yangguo@chromium.org,jgruber@chromium.org
Change-Id: I7b51659d21fe2d49ff343f4de0f6bb9720281b86
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: chromium:1125934
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2465822
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70437}
This commit is contained in:
parent
e2408c2521
commit
f9a31e424c
@ -14,18 +14,12 @@ RegExpStackScope::RegExpStackScope(Isolate* isolate)
|
||||
: regexp_stack_(isolate->regexp_stack()) {
|
||||
// Initialize, if not already initialized.
|
||||
regexp_stack_->EnsureCapacity(0);
|
||||
// Irregexp is not reentrant in several ways; in particular, the
|
||||
// RegExpStackScope is not reentrant since the destructor frees allocated
|
||||
// memory. Protect against reentrancy here.
|
||||
CHECK(!regexp_stack_->is_in_use());
|
||||
regexp_stack_->set_is_in_use(true);
|
||||
}
|
||||
|
||||
|
||||
RegExpStackScope::~RegExpStackScope() {
|
||||
// Reset the buffer if it has grown.
|
||||
regexp_stack_->Reset();
|
||||
DCHECK(!regexp_stack_->is_in_use());
|
||||
}
|
||||
|
||||
RegExpStack::RegExpStack() : thread_local_(this), isolate_(nullptr) {}
|
||||
@ -42,15 +36,17 @@ char* RegExpStack::ArchiveStack(char* to) {
|
||||
DCHECK(thread_local_.owns_memory_);
|
||||
}
|
||||
|
||||
MemCopy(reinterpret_cast<void*>(to), &thread_local_, kThreadLocalSize);
|
||||
size_t size = sizeof(thread_local_);
|
||||
MemCopy(reinterpret_cast<void*>(to), &thread_local_, size);
|
||||
thread_local_ = ThreadLocal(this);
|
||||
return to + kThreadLocalSize;
|
||||
return to + size;
|
||||
}
|
||||
|
||||
|
||||
char* RegExpStack::RestoreStack(char* from) {
|
||||
MemCopy(&thread_local_, reinterpret_cast<void*>(from), kThreadLocalSize);
|
||||
return from + kThreadLocalSize;
|
||||
size_t size = sizeof(thread_local_);
|
||||
MemCopy(&thread_local_, reinterpret_cast<void*>(from), size);
|
||||
return from + size;
|
||||
}
|
||||
|
||||
void RegExpStack::Reset() { thread_local_.ResetToStaticStack(this); }
|
||||
@ -64,7 +60,6 @@ void RegExpStack::ThreadLocal::ResetToStaticStack(RegExpStack* regexp_stack) {
|
||||
limit_ = reinterpret_cast<Address>(regexp_stack->static_stack_) +
|
||||
kStackLimitSlack * kSystemPointerSize;
|
||||
owns_memory_ = false;
|
||||
is_in_use_ = false;
|
||||
}
|
||||
|
||||
void RegExpStack::ThreadLocal::FreeAndInvalidate() {
|
||||
|
@ -68,12 +68,9 @@ class RegExpStack {
|
||||
// If passing zero, the default/minimum size buffer is allocated.
|
||||
Address EnsureCapacity(size_t size);
|
||||
|
||||
bool is_in_use() const { return thread_local_.is_in_use_; }
|
||||
void set_is_in_use(bool v) { thread_local_.is_in_use_ = v; }
|
||||
|
||||
// Thread local archiving.
|
||||
static constexpr int ArchiveSpacePerThread() {
|
||||
return static_cast<int>(kThreadLocalSize);
|
||||
return static_cast<int>(sizeof(ThreadLocal));
|
||||
}
|
||||
char* ArchiveStack(char* to);
|
||||
char* RestoreStack(char* from);
|
||||
@ -115,12 +112,10 @@ class RegExpStack {
|
||||
size_t memory_size_ = 0;
|
||||
Address limit_ = kNullAddress;
|
||||
bool owns_memory_ = false; // Whether memory_ is owned and must be freed.
|
||||
bool is_in_use_ = false; // To guard against reentrancy.
|
||||
|
||||
void ResetToStaticStack(RegExpStack* regexp_stack);
|
||||
void FreeAndInvalidate();
|
||||
};
|
||||
static constexpr size_t kThreadLocalSize = sizeof(ThreadLocal);
|
||||
|
||||
// Address of top of memory used as stack.
|
||||
Address memory_top_address_address() {
|
||||
|
@ -41,10 +41,6 @@
|
||||
'test-serialize/TestThatAlwaysFails': [FAIL],
|
||||
'test-api/SealHandleScope': [FAIL],
|
||||
|
||||
# This test is expected to hit a CHECK (i.e. a FAIL result actually means the
|
||||
# test passed).
|
||||
'test-api/RegExpInterruptAndReenterIrregexp': [FAIL],
|
||||
|
||||
# This test always fails. It tests that LiveEdit causes abort when turned off.
|
||||
'test-debug/LiveEditDisabled': [FAIL],
|
||||
|
||||
|
@ -21435,13 +21435,6 @@ class RegExpInterruptTest {
|
||||
string->MakeExternal(&two_byte_string_resource);
|
||||
}
|
||||
|
||||
static void ReenterIrregexp(v8::Isolate* isolate, void* data) {
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::TryCatch try_catch(isolate);
|
||||
// Irregexp is not reentrant. This should crash.
|
||||
CompileRun("/((a*)*)*b/.exec('aaaaab')");
|
||||
}
|
||||
|
||||
private:
|
||||
static void SignalSemaphore(v8::Isolate* isolate, void* data) {
|
||||
reinterpret_cast<RegExpInterruptTest*>(data)->sem_.Signal();
|
||||
@ -21548,16 +21541,6 @@ TEST(RegExpInterruptAndMakeSubjectTwoByteExternal) {
|
||||
test.RunTest(RegExpInterruptTest::MakeSubjectTwoByteExternal);
|
||||
}
|
||||
|
||||
TEST(RegExpInterruptAndReenterIrregexp) {
|
||||
// We only check in the runtime entry to irregexp, so make sure we don't hit
|
||||
// an interpreter.
|
||||
i::FLAG_regexp_tier_up_ticks = 0;
|
||||
i::FLAG_regexp_interpret_all = false;
|
||||
i::FLAG_enable_experimental_regexp_engine = false;
|
||||
RegExpInterruptTest test;
|
||||
test.RunTest(RegExpInterruptTest::ReenterIrregexp);
|
||||
}
|
||||
|
||||
class RequestInterruptTestBase {
|
||||
public:
|
||||
RequestInterruptTestBase()
|
||||
|
Loading…
Reference in New Issue
Block a user