Version 3.2.4.
Added isolates which allows several V8 instances in the same process. This is controlled through the new Isolate class in the API.
Implemented more of EcmaScript 5 strict mode.
Reduced the time it takes to make detailed heap snapshot.
Added a number of commands to the ARM simulator and enhanced the ARM disassembler.
git-svn-id: http://v8.googlecode.com/svn/trunk@7322 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 8a4f894..2db8ddf 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -35,7 +35,6 @@
#include "platform.h"
#include "string-search.h"
#include "runtime.h"
-#include "top.h"
#include "compilation-cache.h"
#include "string-stream.h"
#include "parser.h"
@@ -62,7 +61,6 @@
namespace v8 {
namespace internal {
-
Handle<Object> RegExpImpl::CreateRegExpLiteral(Handle<JSFunction> constructor,
Handle<String> pattern,
Handle<String> flags,
@@ -97,12 +95,14 @@
Handle<String> pattern,
Handle<String> error_text,
const char* message) {
- Handle<FixedArray> elements = Factory::NewFixedArray(2);
+ Isolate* isolate = re->GetIsolate();
+ Factory* factory = isolate->factory();
+ Handle<FixedArray> elements = factory->NewFixedArray(2);
elements->set(0, *pattern);
elements->set(1, *error_text);
- Handle<JSArray> array = Factory::NewJSArrayWithElements(elements);
- Handle<Object> regexp_err = Factory::NewSyntaxError(message, array);
- Top::Throw(*regexp_err);
+ Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
+ Handle<Object> regexp_err = factory->NewSyntaxError(message, array);
+ isolate->Throw(*regexp_err);
}
@@ -112,10 +112,12 @@
Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
Handle<String> pattern,
Handle<String> flag_str) {
+ Isolate* isolate = re->GetIsolate();
JSRegExp::Flags flags = RegExpFlagsFromString(flag_str);
- Handle<FixedArray> cached = CompilationCache::LookupRegExp(pattern, flags);
+ CompilationCache* compilation_cache = isolate->compilation_cache();
+ Handle<FixedArray> cached = compilation_cache->LookupRegExp(pattern, flags);
bool in_cache = !cached.is_null();
- LOG(RegExpCompileEvent(re, in_cache));
+ LOG(isolate, RegExpCompileEvent(re, in_cache));
Handle<Object> result;
if (in_cache) {
@@ -124,9 +126,9 @@
}
pattern = FlattenGetString(pattern);
CompilationZoneScope zone_scope(DELETE_ON_EXIT);
- PostponeInterruptsScope postpone;
+ PostponeInterruptsScope postpone(isolate);
RegExpCompileData parse_result;
- FlatStringReader reader(pattern);
+ FlatStringReader reader(isolate, pattern);
if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
&parse_result)) {
// Throw an exception if we fail to parse the pattern.
@@ -145,7 +147,8 @@
parse_result.capture_count == 0) {
RegExpAtom* atom = parse_result.tree->AsAtom();
Vector<const uc16> atom_pattern = atom->data();
- Handle<String> atom_string = Factory::NewStringFromTwoByte(atom_pattern);
+ Handle<String> atom_string =
+ isolate->factory()->NewStringFromTwoByte(atom_pattern);
AtomCompile(re, pattern, flags, atom_string);
} else {
IrregexpInitialize(re, pattern, flags, parse_result.capture_count);
@@ -154,7 +157,7 @@
// Compilation succeeded so the data is set on the regexp
// and we can store it in the cache.
Handle<FixedArray> data(FixedArray::cast(re->data()));
- CompilationCache::PutRegExp(pattern, flags, data);
+ compilation_cache->PutRegExp(pattern, flags, data);
return re;
}
@@ -170,7 +173,7 @@
case JSRegExp::IRREGEXP: {
Handle<Object> result =
IrregexpExec(regexp, subject, index, last_match_info);
- ASSERT(!result.is_null() || Top::has_pending_exception());
+ ASSERT(!result.is_null() || Isolate::Current()->has_pending_exception());
return result;
}
default:
@@ -187,11 +190,11 @@
Handle<String> pattern,
JSRegExp::Flags flags,
Handle<String> match_pattern) {
- Factory::SetRegExpAtomData(re,
- JSRegExp::ATOM,
- pattern,
- flags,
- match_pattern);
+ re->GetIsolate()->factory()->SetRegExpAtomData(re,
+ JSRegExp::ATOM,
+ pattern,
+ flags,
+ match_pattern);
}
@@ -224,6 +227,8 @@
Handle<String> subject,
int index,
Handle<JSArray> last_match_info) {
+ Isolate* isolate = re->GetIsolate();
+
ASSERT(0 <= index);
ASSERT(index <= subject->length());
@@ -237,24 +242,30 @@
int needle_len = needle->length();
if (needle_len != 0) {
- if (index + needle_len > subject->length()) return Factory::null_value();
+ if (index + needle_len > subject->length())
+ return isolate->factory()->null_value();
+
// dispatch on type of strings
index = (needle->IsAsciiRepresentation()
? (seq_sub->IsAsciiRepresentation()
- ? SearchString(seq_sub->ToAsciiVector(),
+ ? SearchString(isolate,
+ seq_sub->ToAsciiVector(),
needle->ToAsciiVector(),
index)
- : SearchString(seq_sub->ToUC16Vector(),
+ : SearchString(isolate,
+ seq_sub->ToUC16Vector(),
needle->ToAsciiVector(),
index))
: (seq_sub->IsAsciiRepresentation()
- ? SearchString(seq_sub->ToAsciiVector(),
+ ? SearchString(isolate,
+ seq_sub->ToAsciiVector(),
needle->ToUC16Vector(),
index)
- : SearchString(seq_sub->ToUC16Vector(),
+ : SearchString(isolate,
+ seq_sub->ToUC16Vector(),
needle->ToUC16Vector(),
index)));
- if (index == -1) return Factory::null_value();
+ if (index == -1) return FACTORY->null_value();
}
ASSERT(last_match_info->HasFastElements());
@@ -288,13 +299,14 @@
bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_ascii) {
// Compile the RegExp.
+ Isolate* isolate = re->GetIsolate();
CompilationZoneScope zone_scope(DELETE_ON_EXIT);
- PostponeInterruptsScope postpone;
+ PostponeInterruptsScope postpone(isolate);
Object* entry = re->DataAt(JSRegExp::code_index(is_ascii));
if (entry->IsJSObject()) {
// If it's a JSObject, a previous compilation failed and threw this object.
// Re-throw the object without trying again.
- Top::Throw(entry);
+ isolate->Throw(entry);
return false;
}
ASSERT(entry->IsTheHole());
@@ -307,7 +319,7 @@
}
RegExpCompileData compile_data;
- FlatStringReader reader(pattern);
+ FlatStringReader reader(isolate, pattern);
if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(),
&compile_data)) {
// Throw an exception if we fail to parse the pattern.
@@ -326,15 +338,16 @@
is_ascii);
if (result.error_message != NULL) {
// Unable to compile regexp.
- Handle<FixedArray> elements = Factory::NewFixedArray(2);
+ Factory* factory = isolate->factory();
+ Handle<FixedArray> elements = factory->NewFixedArray(2);
elements->set(0, *pattern);
Handle<String> error_message =
- Factory::NewStringFromUtf8(CStrVector(result.error_message));
+ factory->NewStringFromUtf8(CStrVector(result.error_message));
elements->set(1, *error_message);
- Handle<JSArray> array = Factory::NewJSArrayWithElements(elements);
+ Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
Handle<Object> regexp_err =
- Factory::NewSyntaxError("malformed_regexp", array);
- Top::Throw(*regexp_err);
+ factory->NewSyntaxError("malformed_regexp", array);
+ isolate->Throw(*regexp_err);
re->SetDataAt(JSRegExp::code_index(is_ascii), *regexp_err);
return false;
}
@@ -386,11 +399,11 @@
JSRegExp::Flags flags,
int capture_count) {
// Initialize compiled code entries to null.
- Factory::SetRegExpIrregexpData(re,
- JSRegExp::IRREGEXP,
- pattern,
- flags,
- capture_count);
+ re->GetIsolate()->factory()->SetRegExpIrregexpData(re,
+ JSRegExp::IRREGEXP,
+ pattern,
+ flags,
+ capture_count);
}
@@ -428,7 +441,9 @@
Handle<String> subject,
int index,
Vector<int> output) {
- Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()));
+ Isolate* isolate = regexp->GetIsolate();
+
+ Handle<FixedArray> irregexp(FixedArray::cast(regexp->data()), isolate);
ASSERT(index >= 0);
ASSERT(index <= subject->length());
@@ -436,24 +451,24 @@
// A flat ASCII string might have a two-byte first part.
if (subject->IsConsString()) {
- subject = Handle<String>(ConsString::cast(*subject)->first());
+ subject = Handle<String>(ConsString::cast(*subject)->first(), isolate);
}
#ifndef V8_INTERPRETED_REGEXP
- ASSERT(output.length() >=
- (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
+ ASSERT(output.length() >= (IrregexpNumberOfCaptures(*irregexp) + 1) * 2);
do {
bool is_ascii = subject->IsAsciiRepresentation();
- Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii));
+ Handle<Code> code(IrregexpNativeCode(*irregexp, is_ascii), isolate);
NativeRegExpMacroAssembler::Result res =
NativeRegExpMacroAssembler::Match(code,
subject,
output.start(),
output.length(),
- index);
+ index,
+ isolate);
if (res != NativeRegExpMacroAssembler::RETRY) {
ASSERT(res != NativeRegExpMacroAssembler::EXCEPTION ||
- Top::has_pending_exception());
+ isolate->has_pending_exception());
STATIC_ASSERT(
static_cast<int>(NativeRegExpMacroAssembler::SUCCESS) == RE_SUCCESS);
STATIC_ASSERT(
@@ -484,7 +499,7 @@
for (int i = number_of_capture_registers - 1; i >= 0; i--) {
register_vector[i] = -1;
}
- Handle<ByteArray> byte_codes(IrregexpByteCode(*irregexp, is_ascii));
+ Handle<ByteArray> byte_codes(IrregexpByteCode(*irregexp, is_ascii), isolate);
if (IrregexpInterpreter::Match(byte_codes,
subject,
@@ -516,7 +531,7 @@
int required_registers = RegExpImpl::IrregexpPrepare(jsregexp, subject);
if (required_registers < 0) {
// Compiling failed with an exception.
- ASSERT(Top::has_pending_exception());
+ ASSERT(Isolate::Current()->has_pending_exception());
return Handle<Object>::null();
}
@@ -542,11 +557,11 @@
return last_match_info;
}
if (res == RE_EXCEPTION) {
- ASSERT(Top::has_pending_exception());
+ ASSERT(Isolate::Current()->has_pending_exception());
return Handle<Object>::null();
}
ASSERT(res == RE_FAILURE);
- return Factory::null_value();
+ return Isolate::Current()->factory()->null_value();
}
@@ -1306,16 +1321,14 @@
}
-static unibrow::Mapping<unibrow::Ecma262UnCanonicalize> uncanonicalize;
-static unibrow::Mapping<unibrow::CanonicalizationRange> canonrange;
-
-
// Returns the number of characters in the equivalence class, omitting those
// that cannot occur in the source string because it is ASCII.
-static int GetCaseIndependentLetters(uc16 character,
+static int GetCaseIndependentLetters(Isolate* isolate,
+ uc16 character,
bool ascii_subject,
unibrow::uchar* letters) {
- int length = uncanonicalize.get(character, '\0', letters);
+ int length =
+ isolate->jsregexp_uncanonicalize()->get(character, '\0', letters);
// Unibrow returns 0 or 1 for characters where case independence is
// trivial.
if (length == 0) {
@@ -1331,7 +1344,8 @@
}
-static inline bool EmitSimpleCharacter(RegExpCompiler* compiler,
+static inline bool EmitSimpleCharacter(Isolate* isolate,
+ RegExpCompiler* compiler,
uc16 c,
Label* on_failure,
int cp_offset,
@@ -1353,7 +1367,8 @@
// Only emits non-letters (things that don't have case). Only used for case
// independent matches.
-static inline bool EmitAtomNonLetter(RegExpCompiler* compiler,
+static inline bool EmitAtomNonLetter(Isolate* isolate,
+ RegExpCompiler* compiler,
uc16 c,
Label* on_failure,
int cp_offset,
@@ -1362,7 +1377,7 @@
RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
bool ascii = compiler->ascii();
unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
- int length = GetCaseIndependentLetters(c, ascii, chars);
+ int length = GetCaseIndependentLetters(isolate, c, ascii, chars);
if (length < 1) {
// This can't match. Must be an ASCII subject and a non-ASCII character.
// We do not need to do anything since the ASCII pass already handled this.
@@ -1424,7 +1439,8 @@
}
-typedef bool EmitCharacterFunction(RegExpCompiler* compiler,
+typedef bool EmitCharacterFunction(Isolate* isolate,
+ RegExpCompiler* compiler,
uc16 c,
Label* on_failure,
int cp_offset,
@@ -1433,7 +1449,8 @@
// Only emits letters (things that have case). Only used for case independent
// matches.
-static inline bool EmitAtomLetter(RegExpCompiler* compiler,
+static inline bool EmitAtomLetter(Isolate* isolate,
+ RegExpCompiler* compiler,
uc16 c,
Label* on_failure,
int cp_offset,
@@ -1442,7 +1459,7 @@
RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
bool ascii = compiler->ascii();
unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
- int length = GetCaseIndependentLetters(c, ascii, chars);
+ int length = GetCaseIndependentLetters(isolate, c, ascii, chars);
if (length <= 1) return false;
// We may not need to check against the end of the input string
// if this character lies before a character that matched.
@@ -1880,6 +1897,7 @@
RegExpCompiler* compiler,
int characters_filled_in,
bool not_at_start) {
+ Isolate* isolate = Isolate::Current();
ASSERT(characters_filled_in < details->characters());
int characters = details->characters();
int char_mask;
@@ -1910,7 +1928,8 @@
}
if (compiler->ignore_case()) {
unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
- int length = GetCaseIndependentLetters(c, compiler->ascii(), chars);
+ int length = GetCaseIndependentLetters(isolate, c, compiler->ascii(),
+ chars);
ASSERT(length != 0); // Can only happen if c > char_mask (see above).
if (length == 1) {
// This letter has no case equivalents, so it's nice and simple
@@ -2410,6 +2429,7 @@
Trace* trace,
bool first_element_checked,
int* checked_up_to) {
+ Isolate* isolate = Isolate::Current();
RegExpMacroAssembler* assembler = compiler->macro_assembler();
bool ascii = compiler->ascii();
Label* backtrack = trace->backtrack();
@@ -2445,7 +2465,8 @@
break;
}
if (emit_function != NULL) {
- bool bound_checked = emit_function(compiler,
+ bool bound_checked = emit_function(isolate,
+ compiler,
quarks[j],
backtrack,
cp_offset + j,
@@ -4085,13 +4106,15 @@
}
-static void AddUncanonicals(ZoneList<CharacterRange>* ranges,
+static void AddUncanonicals(Isolate* isolate,
+ ZoneList<CharacterRange>* ranges,
int bottom,
int top);
void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges,
bool is_ascii) {
+ Isolate* isolate = Isolate::Current();
uc16 bottom = from();
uc16 top = to();
if (is_ascii) {
@@ -4101,7 +4124,7 @@
unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
if (top == bottom) {
// If this is a singleton we just expand the one character.
- int length = uncanonicalize.get(bottom, '\0', chars);
+ int length = isolate->jsregexp_uncanonicalize()->get(bottom, '\0', chars);
for (int i = 0; i < length; i++) {
uc32 chr = chars[i];
if (chr != bottom) {
@@ -4130,7 +4153,7 @@
unibrow::uchar range[unibrow::Ecma262UnCanonicalize::kMaxWidth];
int pos = bottom;
while (pos < top) {
- int length = canonrange.get(pos, '\0', range);
+ int length = isolate->jsregexp_canonrange()->get(pos, '\0', range);
uc16 block_end;
if (length == 0) {
block_end = pos;
@@ -4139,7 +4162,7 @@
block_end = range[0];
}
int end = (block_end > top) ? top : block_end;
- length = uncanonicalize.get(block_end, '\0', range);
+ length = isolate->jsregexp_uncanonicalize()->get(block_end, '\0', range);
for (int i = 0; i < length; i++) {
uc32 c = range[i];
uc16 range_from = c - (block_end - pos);
@@ -4249,7 +4272,8 @@
}
-static void AddUncanonicals(ZoneList<CharacterRange>* ranges,
+static void AddUncanonicals(Isolate* isolate,
+ ZoneList<CharacterRange>* ranges,
int bottom,
int top) {
unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
@@ -4281,8 +4305,8 @@
// case mappings.
for (int i = 0; i < boundary_count; i++) {
if (bottom < boundaries[i] && top >= boundaries[i]) {
- AddUncanonicals(ranges, bottom, boundaries[i] - 1);
- AddUncanonicals(ranges, boundaries[i], top);
+ AddUncanonicals(isolate, ranges, bottom, boundaries[i] - 1);
+ AddUncanonicals(isolate, ranges, boundaries[i], top);
return;
}
}
@@ -4293,7 +4317,8 @@
#ifdef DEBUG
for (int j = bottom; j <= top; j++) {
unsigned current_char = j;
- int length = uncanonicalize.get(current_char, '\0', chars);
+ int length = isolate->jsregexp_uncanonicalize()->get(current_char,
+ '\0', chars);
for (int k = 0; k < length; k++) {
ASSERT(chars[k] == current_char);
}
@@ -4306,7 +4331,7 @@
// Step through the range finding equivalent characters.
ZoneList<unibrow::uchar> *characters = new ZoneList<unibrow::uchar>(100);
for (int i = bottom; i <= top; i++) {
- int length = uncanonicalize.get(i, '\0', chars);
+ int length = isolate->jsregexp_uncanonicalize()->get(i, '\0', chars);
for (int j = 0; j < length; j++) {
uc32 chr = chars[j];
if (chr != i && (chr < bottom || chr > top)) {
@@ -4828,7 +4853,7 @@
void Analysis::EnsureAnalyzed(RegExpNode* that) {
- StackLimitCheck check;
+ StackLimitCheck check(Isolate::Current());
if (check.HasOverflowed()) {
fail("Stack overflow");
return;
@@ -5338,7 +5363,4 @@
}
-int OffsetsVector::static_offsets_vector_[
- OffsetsVector::kStaticOffsetsVectorSize];
-
}} // namespace v8::internal