[regexp] Use handle instead of raw object to fix gc issue

The problem was that a raw regexp value was handlified to account for
gc, but then afterwards we used the initial regexp value again instead
of the handle.  This resulted in memory violations if the gc decided to
move the regexp object.

Bug: chrome:1139304,v8:10765,v8:11021
Change-Id: Ib1c31ae4a960523c9939619bcca9606dbb507c81
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2484771
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Martin Bidlingmaier <mbid@google.com>
Cr-Commit-Position: refs/heads/master@{#70605}
This commit is contained in:
Martin Bidlingmaier 2020-10-19 12:02:52 +02:00 committed by Commit Bot
parent 48a99add4e
commit 5c58064423
3 changed files with 12 additions and 11 deletions

View File

@ -255,8 +255,9 @@ MaybeHandle<Object> ExperimentalRegExp::Exec(
}
}
int32_t ExperimentalRegExp::OneshotExecRaw(Isolate* isolate, JSRegExp regexp,
String subject,
int32_t ExperimentalRegExp::OneshotExecRaw(Isolate* isolate,
Handle<JSRegExp> regexp,
Handle<String> subject,
int32_t* output_registers,
int32_t output_register_count,
int32_t subject_index) {
@ -264,18 +265,17 @@ int32_t ExperimentalRegExp::OneshotExecRaw(Isolate* isolate, JSRegExp regexp,
if (FLAG_trace_experimental_regexp_engine) {
StdoutStream{} << "Experimental execution (oneshot) of regexp "
<< regexp.Pattern() << std::endl;
<< regexp->Pattern() << std::endl;
}
Handle<JSRegExp> regexp_handle(regexp, isolate);
base::Optional<CompilationResult> compilation_result =
CompileImpl(isolate, regexp_handle);
CompileImpl(isolate, regexp);
if (!compilation_result.has_value()) return RegExp::kInternalRegExpException;
DisallowHeapAllocation no_gc;
return ExecRawImpl(isolate, RegExp::kFromRuntime,
*compilation_result->bytecode, subject,
regexp.CaptureCount(), output_registers,
*compilation_result->bytecode, *subject,
regexp->CaptureCount(), output_registers,
output_register_count, subject_index);
}
@ -297,7 +297,7 @@ MaybeHandle<Object> ExperimentalRegExp::OneshotExec(
output_registers_release.reset(output_registers);
}
int num_matches = OneshotExecRaw(isolate, *regexp, *subject, output_registers,
int num_matches = OneshotExecRaw(isolate, regexp, subject, output_registers,
output_register_count, subject_index);
if (num_matches > 0) {

View File

@ -49,8 +49,9 @@ class ExperimentalRegExp final : public AllStatic {
static MaybeHandle<Object> OneshotExec(
Isolate* isolate, Handle<JSRegExp> regexp, Handle<String> subject,
int index, Handle<RegExpMatchInfo> last_match_info);
static int32_t OneshotExecRaw(Isolate* isolate, JSRegExp regexp,
String subject, int32_t* output_registers,
static int32_t OneshotExecRaw(Isolate* isolate, Handle<JSRegExp> regexp,
Handle<String> subject,
int32_t* output_registers,
int32_t output_register_count,
int32_t subject_index);

View File

@ -1066,7 +1066,7 @@ int32_t* RegExpGlobalCache::FetchNext() {
// Fall back to experimental engine if needed and possible.
if (num_matches_ == RegExp::kInternalRegExpFallbackToExperimental) {
num_matches_ = ExperimentalRegExp::OneshotExecRaw(
isolate_, *regexp_, *subject_, register_array_, register_array_size_,
isolate_, regexp_, subject_, register_array_, register_array_size_,
last_end_index);
}