Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Unified Diff: src/regexp-macro-assembler.cc

Issue 1034173002: Always update raw pointers when handling interrupts inside RegExp code. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/regexp-macro-assembler.h ('k') | src/x64/regexp-macro-assembler-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/regexp-macro-assembler.cc
diff --git a/src/regexp-macro-assembler.cc b/src/regexp-macro-assembler.cc
index 90ac1b9fa34f61e1b0a3210e043fc7e838d851d5..6228ce4b5337edb4071553dfb153093a095f7365 100644
--- a/src/regexp-macro-assembler.cc
+++ b/src/regexp-macro-assembler.cc
@@ -42,30 +42,82 @@ bool NativeRegExpMacroAssembler::CanReadUnaligned() {
const byte* NativeRegExpMacroAssembler::StringCharacterPosition(
String* subject,
int start_index) {
- // Not just flat, but ultra flat.
- DCHECK(subject->IsExternalString() || subject->IsSeqString());
+ if (subject->IsConsString()) {
+ subject = ConsString::cast(subject)->first();
+ } else if (subject->IsSlicedString()) {
+ start_index += SlicedString::cast(subject)->offset();
+ subject = SlicedString::cast(subject)->parent();
+ }
DCHECK(start_index >= 0);
DCHECK(start_index <= subject->length());
- if (subject->IsOneByteRepresentation()) {
- const byte* address;
- if (StringShape(subject).IsExternal()) {
- const uint8_t* data = ExternalOneByteString::cast(subject)->GetChars();
- address = reinterpret_cast<const byte*>(data);
- } else {
- DCHECK(subject->IsSeqOneByteString());
- const uint8_t* data = SeqOneByteString::cast(subject)->GetChars();
- address = reinterpret_cast<const byte*>(data);
- }
- return address + start_index;
+ if (subject->IsSeqOneByteString()) {
+ return reinterpret_cast<const byte*>(
+ SeqOneByteString::cast(subject)->GetChars() + start_index);
+ } else if (subject->IsSeqTwoByteString()) {
+ return reinterpret_cast<const byte*>(
+ SeqTwoByteString::cast(subject)->GetChars() + start_index);
+ } else if (subject->IsExternalOneByteString()) {
+ return reinterpret_cast<const byte*>(
+ ExternalOneByteString::cast(subject)->GetChars() + start_index);
+ } else {
+ return reinterpret_cast<const byte*>(
+ ExternalTwoByteString::cast(subject)->GetChars() + start_index);
}
- const uc16* data;
- if (StringShape(subject).IsExternal()) {
- data = ExternalTwoByteString::cast(subject)->GetChars();
+}
+
+
+int NativeRegExpMacroAssembler::CheckStackGuardState(
+ Isolate* isolate, int start_index, bool is_direct_call,
+ Address* return_address, Code* re_code, String** subject,
+ const byte** input_start, const byte** input_end) {
+ DCHECK(re_code->instruction_start() <= *return_address);
+ DCHECK(*return_address <= re_code->instruction_end());
+ int return_value = 0;
+ // Prepare for possible GC.
+ HandleScope handles(isolate);
+ Handle<Code> code_handle(re_code);
+ Handle<String> subject_handle(*subject);
+ bool is_one_byte = subject_handle->IsOneByteRepresentationUnderneath();
+
+ StackLimitCheck check(isolate);
+ if (check.JsHasOverflowed()) {
+ isolate->StackOverflow();
+ return_value = EXCEPTION;
+ } else if (is_direct_call) {
+ // If not real stack overflow the stack guard was used to interrupt
+ // execution for another purpose. If this is a direct call from JavaScript
+ // retry the RegExp forcing the call through the runtime system.
+ // Currently the direct call cannot handle a GC.
+ return_value = RETRY;
} else {
- DCHECK(subject->IsSeqTwoByteString());
- data = SeqTwoByteString::cast(subject)->GetChars();
+ Object* result = isolate->stack_guard()->HandleInterrupts();
+ if (result->IsException()) return_value = EXCEPTION;
+ }
+
+ DisallowHeapAllocation no_gc;
+
+ if (*code_handle != re_code) { // Return address no longer valid
+ intptr_t delta = code_handle->address() - re_code->address();
+ // Overwrite the return address on the stack.
+ *return_address += delta;
+ }
+
+ // If we continue, we need to update the subject string addresses.
+ if (return_value == 0) {
+ // String encoding might have changed.
+ if (subject_handle->IsOneByteRepresentationUnderneath() != is_one_byte) {
+ // If we changed between an LATIN1 and an UC16 string, the specialized
+ // code cannot be used, and we need to restart regexp matching from
+ // scratch (including, potentially, compiling a new version of the code).
+ return_value = RETRY;
+ } else {
+ *subject = *subject_handle;
+ intptr_t byte_length = *input_end - *input_start;
+ *input_start = StringCharacterPosition(*subject, start_index);
+ *input_end = *input_start + byte_length;
+ }
}
- return reinterpret_cast<const byte*>(data + start_index);
+ return return_value;
}
« no previous file with comments | « src/regexp-macro-assembler.h ('k') | src/x64/regexp-macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698