Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Upgrade V8 to 3.5.8

  • Loading branch information...
commit 028908ab7cc576d3013960a4580fcd9bf21cc26e 1 parent 8af0abd
@ry ry authored
Showing with 731 additions and 402 deletions.
  1. +11 −0 deps/v8/ChangeLog
  2. 0  deps/v8/include/v8-debug.h
  3. +11 −10 deps/v8/include/v8.h
  4. 0  deps/v8/src/SConscript
  5. +12 −10 deps/v8/src/api.cc
  6. +3 −0  deps/v8/src/arm/assembler-arm.h
  7. +15 −17 deps/v8/src/arm/code-stubs-arm.cc
  8. +0 −3  deps/v8/src/arm/full-codegen-arm.cc
  9. +0 −1  deps/v8/src/arm/lithium-arm.cc
  10. +0 −3  deps/v8/src/arm/lithium-codegen-arm.cc
  11. +1 −3 deps/v8/src/arm/lithium-gap-resolver-arm.cc
  12. +2 −3 deps/v8/src/arm/stub-cache-arm.cc
  13. +23 −24 deps/v8/src/ast.cc
  14. +46 −28 deps/v8/src/ast.h
  15. 0  deps/v8/src/compiler.cc
  16. +4 −2 deps/v8/src/d8.cc
  17. +5 −3 deps/v8/src/handles.cc
  18. +21 −2 deps/v8/src/hydrogen-instructions.cc
  19. +16 −12 deps/v8/src/hydrogen-instructions.h
  20. +22 −20 deps/v8/src/hydrogen.cc
  21. +2 −2 deps/v8/src/hydrogen.h
  22. +6 −4 deps/v8/src/interpreter-irregexp.cc
  23. +19 −27 deps/v8/src/jsregexp.cc
  24. +7 −5 deps/v8/src/messages.js
  25. +5 −0 deps/v8/src/objects-inl.h
  26. +55 −66 deps/v8/src/objects.cc
  27. +55 −5 deps/v8/src/objects.h
  28. +27 −9 deps/v8/src/profile-generator.cc
  29. +2 −3 deps/v8/src/profile-generator.h
  30. +116 −96 deps/v8/src/runtime.cc
  31. 0  deps/v8/src/scanner.cc
  32. +25 −0 deps/v8/src/small-pointer-list.h
  33. +1 −1  deps/v8/src/string.js
  34. +2 −1  deps/v8/src/stub-cache.cc
  35. +3 −1 deps/v8/src/stub-cache.h
  36. +21 −24 deps/v8/src/type-info.cc
  37. +20 −12 deps/v8/src/type-info.h
  38. +1 −1  deps/v8/src/version.cc
  39. +0 −4 deps/v8/src/zone.h
  40. +41 −0 deps/v8/test/cctest/test-api.cc
  41. +56 −0 deps/v8/test/cctest/test-heap-profiler.cc
  42. +31 −0 deps/v8/test/message/replacement-marker-as-argument.js
  43. +32 −0 deps/v8/test/message/replacement-marker-as-argument.out
  44. +12 −0 deps/v8/test/mjsunit/string-split.js
View
11 deps/v8/ChangeLog
@@ -1,3 +1,14 @@
+2011-08-24: Version 3.5.8
+
+ Added V8EXPORT attributes for v8::Array::CheckCast and
+ v8::Number::CheckCast.
+
+ Made a slight API change enabling opting out from null termination
+ in String::Write*().
+
+ Fixed arm build for gcc-4.6.
+
+
2011-08-22: Version 3.5.7
Make scanner handle invalid unicode escapes in identifiers correctly.
View
0  deps/v8/include/v8-debug.h 100755 → 100644
File mode changed
View
21 deps/v8/include/v8.h
@@ -1039,29 +1039,30 @@ class String : public Primitive {
* \param length The number of characters to copy from the string. For
* WriteUtf8 the number of bytes in the buffer.
* \param nchars_ref The number of characters written, can be NULL.
- * \param hints Various hints that might affect performance of this or
+ * \param options Various options that might affect performance of this or
* subsequent operations.
* \return The number of characters copied to the buffer excluding the null
* terminator. For WriteUtf8: The number of bytes copied to the buffer
- * including the null terminator.
+ * including the null terminator (if written).
*/
- enum WriteHints {
- NO_HINTS = 0,
- HINT_MANY_WRITES_EXPECTED = 1
+ enum WriteOptions {
+ NO_OPTIONS = 0,
+ HINT_MANY_WRITES_EXPECTED = 1,
+ NO_NULL_TERMINATION = 2
};
V8EXPORT int Write(uint16_t* buffer,
int start = 0,
int length = -1,
- WriteHints hints = NO_HINTS) const; // UTF-16
+ int options = NO_OPTIONS) const; // UTF-16
V8EXPORT int WriteAscii(char* buffer,
int start = 0,
int length = -1,
- WriteHints hints = NO_HINTS) const; // ASCII
+ int options = NO_OPTIONS) const; // ASCII
V8EXPORT int WriteUtf8(char* buffer,
int length = -1,
int* nchars_ref = NULL,
- WriteHints hints = NO_HINTS) const; // UTF-8
+ int options = NO_OPTIONS) const; // UTF-8
/**
* A zero length string.
@@ -1335,7 +1336,7 @@ class Number : public Primitive {
static inline Number* Cast(v8::Value* obj);
private:
V8EXPORT Number();
- static void CheckCast(v8::Value* obj);
+ V8EXPORT static void CheckCast(v8::Value* obj);
};
@@ -1709,7 +1710,7 @@ class Array : public Object {
static inline Array* Cast(Value* obj);
private:
V8EXPORT Array();
- static void CheckCast(Value* obj);
+ V8EXPORT static void CheckCast(Value* obj);
};
View
0  deps/v8/src/SConscript 100755 → 100644
File mode changed
View
22 deps/v8/src/api.cc
@@ -3621,7 +3621,7 @@ int String::Utf8Length() const {
int String::WriteUtf8(char* buffer,
int capacity,
int* nchars_ref,
- WriteHints hints) const {
+ int options) const {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::String::WriteUtf8()")) return 0;
LOG_API(isolate, "String::WriteUtf8");
@@ -3629,7 +3629,7 @@ int String::WriteUtf8(char* buffer,
i::StringInputBuffer& write_input_buffer = *isolate->write_input_buffer();
i::Handle<i::String> str = Utils::OpenHandle(this);
isolate->string_tracker()->RecordWrite(str);
- if (hints & HINT_MANY_WRITES_EXPECTED) {
+ if (options & HINT_MANY_WRITES_EXPECTED) {
// Flatten the string for efficiency. This applies whether we are
// using StringInputBuffer or Get(i) to access the characters.
str->TryFlatten();
@@ -3669,7 +3669,8 @@ int String::WriteUtf8(char* buffer,
}
}
if (nchars_ref != NULL) *nchars_ref = nchars;
- if (i == len && (capacity == -1 || pos < capacity))
+ if (!(options & NO_NULL_TERMINATION) &&
+ (i == len && (capacity == -1 || pos < capacity)))
buffer[pos++] = '\0';
return pos;
}
@@ -3678,7 +3679,7 @@ int String::WriteUtf8(char* buffer,
int String::WriteAscii(char* buffer,
int start,
int length,
- WriteHints hints) const {
+ int options) const {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::String::WriteAscii()")) return 0;
LOG_API(isolate, "String::WriteAscii");
@@ -3687,7 +3688,7 @@ int String::WriteAscii(char* buffer,
ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(this);
isolate->string_tracker()->RecordWrite(str);
- if (hints & HINT_MANY_WRITES_EXPECTED) {
+ if (options & HINT_MANY_WRITES_EXPECTED) {
// Flatten the string for efficiency. This applies whether we are
// using StringInputBuffer or Get(i) to access the characters.
str->TryFlatten();
@@ -3703,7 +3704,7 @@ int String::WriteAscii(char* buffer,
if (c == '\0') c = ' ';
buffer[i] = c;
}
- if (length == -1 || i < length)
+ if (!(options & NO_NULL_TERMINATION) && (length == -1 || i < length))
buffer[i] = '\0';
return i;
}
@@ -3712,7 +3713,7 @@ int String::WriteAscii(char* buffer,
int String::Write(uint16_t* buffer,
int start,
int length,
- WriteHints hints) const {
+ int options) const {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::String::Write()")) return 0;
LOG_API(isolate, "String::Write");
@@ -3720,7 +3721,7 @@ int String::Write(uint16_t* buffer,
ASSERT(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(this);
isolate->string_tracker()->RecordWrite(str);
- if (hints & HINT_MANY_WRITES_EXPECTED) {
+ if (options & HINT_MANY_WRITES_EXPECTED) {
// Flatten the string for efficiency. This applies whether we are
// using StringInputBuffer or Get(i) to access the characters.
str->TryFlatten();
@@ -3730,7 +3731,8 @@ int String::Write(uint16_t* buffer,
end = str->length();
if (end < 0) return 0;
i::String::WriteToFlat(*str, buffer, start, end);
- if (length == -1 || end - start < length) {
+ if (!(options & NO_NULL_TERMINATION) &&
+ (length == -1 || end - start < length)) {
buffer[end - start] = '\0';
}
return end - start;
@@ -4118,7 +4120,7 @@ bool Context::InContext() {
v8::Local<v8::Context> Context::GetEntered() {
i::Isolate* isolate = i::Isolate::Current();
- if (IsDeadCheck(isolate, "v8::Context::GetEntered()")) {
+ if (!EnsureInitializedForIsolate(isolate, "v8::Context::GetEntered()")) {
return Local<Context>();
}
i::Handle<i::Object> last =
View
3  deps/v8/src/arm/assembler-arm.h
@@ -377,6 +377,9 @@ class Operand BASE_EMBEDDED {
// immediate
INLINE(explicit Operand(int32_t immediate,
RelocInfo::Mode rmode = RelocInfo::NONE));
+ INLINE(static Operand Zero()) {
+ return Operand(static_cast<int32_t>(0));
+ }
INLINE(explicit Operand(const ExternalReference& f));
explicit Operand(Handle<Object> handle);
INLINE(explicit Operand(Smi* value));
View
32 deps/v8/src/arm/code-stubs-arm.cc
@@ -549,7 +549,7 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
// | s | exp | mantissa |
// Check for zero.
- __ cmp(int_scratch, Operand(0));
+ __ cmp(int_scratch, Operand::Zero());
__ mov(dst2, int_scratch);
__ mov(dst1, int_scratch);
__ b(eq, &done);
@@ -557,7 +557,7 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
// Preload the sign of the value.
__ and_(dst2, int_scratch, Operand(HeapNumber::kSignMask), SetCC);
// Get the absolute value of the object (as an unsigned integer).
- __ rsb(int_scratch, int_scratch, Operand(0), SetCC, mi);
+ __ rsb(int_scratch, int_scratch, Operand::Zero(), SetCC, mi);
// Get mantisssa[51:20].
@@ -589,7 +589,7 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
__ mov(scratch2, Operand(int_scratch, LSL, scratch2));
__ orr(dst2, dst2, scratch2);
// Set dst1 to 0.
- __ mov(dst1, Operand(0));
+ __ mov(dst1, Operand::Zero());
}
__ bind(&done);
}
@@ -657,7 +657,7 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
// Check for 0 and -0.
__ bic(scratch1, dst1, Operand(HeapNumber::kSignMask));
__ orr(scratch1, scratch1, Operand(dst2));
- __ cmp(scratch1, Operand(0));
+ __ cmp(scratch1, Operand::Zero());
__ b(eq, &done);
// Check that the value can be exactly represented by a 32-bit integer.
@@ -730,7 +730,7 @@ void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
// Check for 0 and -0.
__ bic(dst, scratch1, Operand(HeapNumber::kSignMask));
__ orr(dst, scratch2, Operand(dst));
- __ cmp(dst, Operand(0));
+ __ cmp(dst, Operand::Zero());
__ b(eq, &done);
DoubleIs32BitInteger(masm, scratch1, scratch2, dst, scratch3, not_int32);
@@ -747,7 +747,7 @@ void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
// Set the sign.
__ ldr(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
__ tst(scratch1, Operand(HeapNumber::kSignMask));
- __ rsb(dst, dst, Operand(0), LeaveCC, mi);
+ __ rsb(dst, dst, Operand::Zero(), LeaveCC, mi);
}
__ bind(&done);
@@ -2424,7 +2424,6 @@ void BinaryOpStub::GenerateSmiCode(
Register left = r1;
Register right = r0;
Register scratch1 = r7;
- Register scratch2 = r9;
// Perform combined smi check on both operands.
__ orr(scratch1, left, Operand(right));
@@ -2618,7 +2617,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
__ b(mi, &return_heap_number);
// Check for minus zero. Return heap number for minus zero.
Label not_zero;
- __ cmp(scratch1, Operand(0));
+ __ cmp(scratch1, Operand::Zero());
__ b(ne, &not_zero);
__ vmov(scratch2, d5.high());
__ tst(scratch2, Operand(HeapNumber::kSignMask));
@@ -3110,7 +3109,6 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
Label no_update;
Label skip_cache;
- const Register heap_number_map = r5;
// Call C function to calculate the result and update the cache.
// Register r0 holds precalculated cache entry address; preserve
@@ -3581,7 +3579,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate);
__ mov(r5, Operand(ExternalReference(js_entry_sp)));
__ ldr(r6, MemOperand(r5));
- __ cmp(r6, Operand(0));
+ __ cmp(r6, Operand::Zero());
__ b(ne, &non_outermost_js);
__ str(fp, MemOperand(r5));
__ mov(ip, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
@@ -3656,7 +3654,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ pop(r5);
__ cmp(r5, Operand(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
__ b(ne, &non_outermost_js_2);
- __ mov(r6, Operand(0));
+ __ mov(r6, Operand::Zero());
__ mov(r5, Operand(ExternalReference(js_entry_sp)));
__ str(r6, MemOperand(r5));
__ bind(&non_outermost_js_2);
@@ -3857,7 +3855,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ Push(r0, r1);
__ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION);
__ LeaveInternalFrame();
- __ cmp(r0, Operand(0));
+ __ cmp(r0, Operand::Zero());
__ LoadRoot(r0, Heap::kTrueValueRootIndex, eq);
__ LoadRoot(r0, Heap::kFalseValueRootIndex, ne);
__ Ret(HasArgsInRegisters() ? 0 : 2);
@@ -3991,7 +3989,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
FixedArray::kHeaderSize + 2 * kPointerSize;
// If there are no mapped parameters, we do not need the parameter_map.
__ cmp(r1, Operand(Smi::FromInt(0)));
- __ mov(r9, Operand(0), LeaveCC, eq);
+ __ mov(r9, Operand::Zero(), LeaveCC, eq);
__ mov(r9, Operand(r1, LSL, 1), LeaveCC, ne);
__ add(r9, r9, Operand(kParameterMapHeaderSize), LeaveCC, ne);
@@ -4015,7 +4013,7 @@ void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) {
__ ldr(r4, MemOperand(r8, Context::SlotOffset(Context::GLOBAL_INDEX)));
__ ldr(r4, FieldMemOperand(r4, GlobalObject::kGlobalContextOffset));
- __ cmp(r1, Operand(0));
+ __ cmp(r1, Operand::Zero());
__ ldr(r4, MemOperand(r4, kNormalOffset), eq);
__ ldr(r4, MemOperand(r4, kAliasedOffset), ne);
@@ -5697,7 +5695,7 @@ void StringCompareStub::GenerateAsciiCharsCompareLoop(
Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
__ add(left, left, Operand(scratch1));
__ add(right, right, Operand(scratch1));
- __ rsb(length, length, Operand(0));
+ __ rsb(length, length, Operand::Zero());
Register index = length; // index = -length;
// Compare loop.
@@ -6555,7 +6553,7 @@ void StringDictionaryLookupStub::Generate(MacroAssembler* masm) {
// treated as a lookup success. For positive lookup probing failure
// should be treated as lookup failure.
if (mode_ == POSITIVE_LOOKUP) {
- __ mov(result, Operand(0));
+ __ mov(result, Operand::Zero());
__ Ret();
}
@@ -6564,7 +6562,7 @@ void StringDictionaryLookupStub::Generate(MacroAssembler* masm) {
__ Ret();
__ bind(&not_in_dictionary);
- __ mov(result, Operand(0));
+ __ mov(result, Operand::Zero());
__ Ret();
}
View
3  deps/v8/src/arm/full-codegen-arm.cc
@@ -4129,11 +4129,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
default: {
VisitForAccumulatorValue(expr->right());
Condition cond = eq;
- bool strict = false;
switch (op) {
case Token::EQ_STRICT:
- strict = true;
- // Fall through
case Token::EQ:
cond = eq;
__ pop(r1);
View
1  deps/v8/src/arm/lithium-arm.cc
@@ -1399,7 +1399,6 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
Token::Value op = instr->token();
- Representation r = instr->GetInputRepresentation();
ASSERT(instr->left()->representation().IsTagged());
ASSERT(instr->right()->representation().IsTagged());
bool reversed = (op == Token::GT || op == Token::LTE);
View
3  deps/v8/src/arm/lithium-codegen-arm.cc
@@ -1804,7 +1804,6 @@ Condition LCodeGen::EmitIsObject(Register input,
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
Register reg = ToRegister(instr->InputAt(0));
Register temp1 = ToRegister(instr->TempAt(0));
- Register temp2 = scratch0();
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
@@ -2759,7 +2758,6 @@ void LCodeGen::DoOuterContext(LOuterContext* instr) {
void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
- Register context = ToRegister(instr->context());
Register result = ToRegister(instr->result());
__ ldr(result, ContextOperand(cp, Context::GLOBAL_INDEX));
}
@@ -3965,7 +3963,6 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
Register scratch1 = scratch0();
Register scratch2 = ToRegister(instr->TempAt(0));
DwVfpRegister double_input = ToDoubleRegister(instr->InputAt(0));
- DwVfpRegister double_scratch = double_scratch0();
SwVfpRegister single_scratch = double_scratch0().low();
Label done;
View
4 deps/v8/src/arm/lithium-gap-resolver-arm.cc
@@ -254,7 +254,6 @@ void LGapResolver::EmitMove(int index) {
} else {
ASSERT(destination->IsStackSlot());
ASSERT(!in_cycle_); // Constant moves happen after all cycles are gone.
- MemOperand destination_operand = cgen_->ToMemOperand(destination);
__ mov(kSavedValueRegister, source_operand);
__ str(kSavedValueRegister, cgen_->ToMemOperand(destination));
}
@@ -265,8 +264,7 @@ void LGapResolver::EmitMove(int index) {
__ vmov(cgen_->ToDoubleRegister(destination), source_register);
} else {
ASSERT(destination->IsDoubleStackSlot());
- MemOperand destination_operand = cgen_->ToMemOperand(destination);
- __ vstr(source_register, destination_operand);
+ __ vstr(source_register, cgen_->ToMemOperand(destination));
}
} else if (source->IsDoubleStackSlot()) {
View
5 deps/v8/src/arm/stub-cache-arm.cc
@@ -1183,9 +1183,8 @@ void StubCompiler::GenerateLoadConstant(JSObject* object,
__ JumpIfSmi(receiver, miss);
// Check that the maps haven't changed.
- Register reg =
- CheckPrototypes(object, receiver, holder,
- scratch1, scratch2, scratch3, name, miss);
+ CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, name,
+ miss);
// Return the constant value.
__ mov(r0, Operand(Handle<Object>(value)));
View
47 deps/v8/src/ast.cc
@@ -139,8 +139,7 @@ Assignment::Assignment(Isolate* isolate,
assignment_id_(GetNextId(isolate)),
block_start_(false),
block_end_(false),
- is_monomorphic_(false),
- receiver_types_(NULL) {
+ is_monomorphic_(false) {
ASSERT(Token::IsAssignmentOp(op));
if (is_compound()) {
binary_operation_ =
@@ -652,6 +651,7 @@ bool CountOperation::IsInlineable() const {
void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
// Record type feedback from the oracle in the AST.
is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
+ receiver_types_.Clear();
if (key()->IsPropertyName()) {
if (oracle->LoadIsBuiltin(this, Builtins::kLoadIC_ArrayLength)) {
is_array_length_ = true;
@@ -664,16 +664,15 @@ void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
Literal* lit_key = key()->AsLiteral();
ASSERT(lit_key != NULL && lit_key->handle()->IsString());
Handle<String> name = Handle<String>::cast(lit_key->handle());
- ZoneMapList* types = oracle->LoadReceiverTypes(this, name);
- receiver_types_ = types;
+ oracle->LoadReceiverTypes(this, name, &receiver_types_);
}
} else if (oracle->LoadIsBuiltin(this, Builtins::kKeyedLoadIC_String)) {
is_string_access_ = true;
} else if (is_monomorphic_) {
- monomorphic_receiver_type_ = oracle->LoadMonomorphicReceiverType(this);
+ receiver_types_.Add(oracle->LoadMonomorphicReceiverType(this));
} else if (oracle->LoadIsMegamorphicWithTypeInfo(this)) {
- receiver_types_ = new ZoneMapList(kMaxKeyedPolymorphism);
- oracle->CollectKeyedReceiverTypes(this->id(), receiver_types_);
+ receiver_types_.Reserve(kMaxKeyedPolymorphism);
+ oracle->CollectKeyedReceiverTypes(this->id(), &receiver_types_);
}
}
@@ -682,30 +681,31 @@ void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
Property* prop = target()->AsProperty();
ASSERT(prop != NULL);
is_monomorphic_ = oracle->StoreIsMonomorphicNormal(this);
+ receiver_types_.Clear();
if (prop->key()->IsPropertyName()) {
Literal* lit_key = prop->key()->AsLiteral();
ASSERT(lit_key != NULL && lit_key->handle()->IsString());
Handle<String> name = Handle<String>::cast(lit_key->handle());
- ZoneMapList* types = oracle->StoreReceiverTypes(this, name);
- receiver_types_ = types;
+ oracle->StoreReceiverTypes(this, name, &receiver_types_);
} else if (is_monomorphic_) {
// Record receiver type for monomorphic keyed stores.
- monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this);
+ receiver_types_.Add(oracle->StoreMonomorphicReceiverType(this));
} else if (oracle->StoreIsMegamorphicWithTypeInfo(this)) {
- receiver_types_ = new ZoneMapList(kMaxKeyedPolymorphism);
- oracle->CollectKeyedReceiverTypes(this->id(), receiver_types_);
+ receiver_types_.Reserve(kMaxKeyedPolymorphism);
+ oracle->CollectKeyedReceiverTypes(this->id(), &receiver_types_);
}
}
void CountOperation::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
is_monomorphic_ = oracle->StoreIsMonomorphicNormal(this);
+ receiver_types_.Clear();
if (is_monomorphic_) {
// Record receiver type for monomorphic keyed stores.
- monomorphic_receiver_type_ = oracle->StoreMonomorphicReceiverType(this);
+ receiver_types_.Add(oracle->StoreMonomorphicReceiverType(this));
} else if (oracle->StoreIsMegamorphicWithTypeInfo(this)) {
- receiver_types_ = new ZoneMapList(kMaxKeyedPolymorphism);
- oracle->CollectKeyedReceiverTypes(this->id(), receiver_types_);
+ receiver_types_.Reserve(kMaxKeyedPolymorphism);
+ oracle->CollectKeyedReceiverTypes(this->id(), &receiver_types_);
}
}
@@ -789,15 +789,14 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle,
Literal* key = property->key()->AsLiteral();
ASSERT(key != NULL && key->handle()->IsString());
Handle<String> name = Handle<String>::cast(key->handle());
- receiver_types_ = oracle->CallReceiverTypes(this, name, call_kind);
+ receiver_types_.Clear();
+ oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_);
#ifdef DEBUG
if (FLAG_enable_slow_asserts) {
- if (receiver_types_ != NULL) {
- int length = receiver_types_->length();
- for (int i = 0; i < length; i++) {
- Handle<Map> map = receiver_types_->at(i);
- ASSERT(!map.is_null() && *map != NULL);
- }
+ int length = receiver_types_.length();
+ for (int i = 0; i < length; i++) {
+ Handle<Map> map = receiver_types_.at(i);
+ ASSERT(!map.is_null() && *map != NULL);
}
}
#endif
@@ -805,9 +804,9 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle,
check_type_ = oracle->GetCallCheckType(this);
if (is_monomorphic_) {
Handle<Map> map;
- if (receiver_types_ != NULL && receiver_types_->length() > 0) {
+ if (receiver_types_.length() > 0) {
ASSERT(check_type_ == RECEIVER_MAP_CHECK);
- map = receiver_types_->at(0);
+ map = receiver_types_.at(0);
} else {
ASSERT(check_type_ != RECEIVER_MAP_CHECK);
holder_ = Handle<JSObject>(
View
74 deps/v8/src/ast.h
@@ -33,6 +33,7 @@
#include "factory.h"
#include "jsregexp.h"
#include "runtime.h"
+#include "small-pointer-list.h"
#include "token.h"
#include "variables.h"
@@ -207,6 +208,36 @@ class Statement: public AstNode {
};
+class SmallMapList {
+ public:
+ SmallMapList() {}
+ explicit SmallMapList(int capacity) : list_(capacity) {}
+
+ void Reserve(int capacity) { list_.Reserve(capacity); }
+ void Clear() { list_.Clear(); }
+
+ bool is_empty() const { return list_.is_empty(); }
+ int length() const { return list_.length(); }
+
+ void Add(Handle<Map> handle) {
+ list_.Add(handle.location());
+ }
+
+ Handle<Map> at(int i) const {
+ return Handle<Map>(list_.at(i));
+ }
+
+ Handle<Map> first() const { return at(0); }
+ Handle<Map> last() const { return at(length() - 1); }
+
+ private:
+ // The list stores pointers to Map*, that is Map**, so it's GC safe.
+ SmallPointerList<Map*> list_;
+
+ DISALLOW_COPY_AND_ASSIGN(SmallMapList);
+};
+
+
class Expression: public AstNode {
public:
enum Context {
@@ -265,13 +296,15 @@ class Expression: public AstNode {
UNREACHABLE();
return false;
}
- virtual ZoneMapList* GetReceiverTypes() {
+ virtual SmallMapList* GetReceiverTypes() {
UNREACHABLE();
return NULL;
}
- virtual Handle<Map> GetMonomorphicReceiverType() {
- UNREACHABLE();
- return Handle<Map>();
+ Handle<Map> GetMonomorphicReceiverType() {
+ ASSERT(IsMonomorphic());
+ SmallMapList* types = GetReceiverTypes();
+ ASSERT(types != NULL && types->length() == 1);
+ return types->at(0);
}
unsigned id() const { return id_; }
@@ -1213,7 +1246,6 @@ class Property: public Expression {
key_(key),
pos_(pos),
type_(type),
- receiver_types_(NULL),
is_monomorphic_(false),
is_array_length_(false),
is_string_length_(false),
@@ -1237,11 +1269,8 @@ class Property: public Expression {
// Type feedback information.
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
virtual bool IsMonomorphic() { return is_monomorphic_; }
- virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
+ virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
virtual bool IsArrayLength() { return is_array_length_; }
- virtual Handle<Map> GetMonomorphicReceiverType() {
- return monomorphic_receiver_type_;
- }
private:
Expression* obj_;
@@ -1249,13 +1278,12 @@ class Property: public Expression {
int pos_;
Type type_;
- ZoneMapList* receiver_types_;
+ SmallMapList receiver_types_;
bool is_monomorphic_ : 1;
bool is_array_length_ : 1;
bool is_string_length_ : 1;
bool is_string_access_ : 1;
bool is_function_prototype_ : 1;
- Handle<Map> monomorphic_receiver_type_;
};
@@ -1271,7 +1299,6 @@ class Call: public Expression {
pos_(pos),
is_monomorphic_(false),
check_type_(RECEIVER_MAP_CHECK),
- receiver_types_(NULL),
return_id_(GetNextId(isolate)) {
}
@@ -1285,7 +1312,7 @@ class Call: public Expression {
void RecordTypeFeedback(TypeFeedbackOracle* oracle,
CallKind call_kind);
- virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
+ virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
virtual bool IsMonomorphic() { return is_monomorphic_; }
CheckType check_type() const { return check_type_; }
Handle<JSFunction> target() { return target_; }
@@ -1310,7 +1337,7 @@ class Call: public Expression {
bool is_monomorphic_;
CheckType check_type_;
- ZoneMapList* receiver_types_;
+ SmallMapList receiver_types_;
Handle<JSFunction> target_;
Handle<JSObject> holder_;
Handle<JSGlobalPropertyCell> cell_;
@@ -1485,8 +1512,7 @@ class CountOperation: public Expression {
expression_(expr),
pos_(pos),
assignment_id_(GetNextId(isolate)),
- count_id_(GetNextId(isolate)),
- receiver_types_(NULL) { }
+ count_id_(GetNextId(isolate)) {}
DECLARE_NODE_TYPE(CountOperation)
@@ -1507,10 +1533,7 @@ class CountOperation: public Expression {
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
virtual bool IsMonomorphic() { return is_monomorphic_; }
- virtual Handle<Map> GetMonomorphicReceiverType() {
- return monomorphic_receiver_type_;
- }
- virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
+ virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
// Bailout support.
int AssignmentId() const { return assignment_id_; }
@@ -1524,8 +1547,7 @@ class CountOperation: public Expression {
int pos_;
int assignment_id_;
int count_id_;
- Handle<Map> monomorphic_receiver_type_;
- ZoneMapList* receiver_types_;
+ SmallMapList receiver_types_;
};
@@ -1673,10 +1695,7 @@ class Assignment: public Expression {
// Type feedback information.
void RecordTypeFeedback(TypeFeedbackOracle* oracle);
virtual bool IsMonomorphic() { return is_monomorphic_; }
- virtual ZoneMapList* GetReceiverTypes() { return receiver_types_; }
- virtual Handle<Map> GetMonomorphicReceiverType() {
- return monomorphic_receiver_type_;
- }
+ virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
// Bailout support.
int CompoundLoadId() const { return compound_load_id_; }
@@ -1695,8 +1714,7 @@ class Assignment: public Expression {
bool block_end_;
bool is_monomorphic_;
- ZoneMapList* receiver_types_;
- Handle<Map> monomorphic_receiver_type_;
+ SmallMapList receiver_types_;
};
View
0  deps/v8/src/compiler.cc 100755 → 100644
File mode changed
View
6 deps/v8/src/d8.cc
@@ -1237,8 +1237,6 @@ int Shell::RunMain(int argc, char* argv[]) {
thread->Join();
delete thread;
}
-
- OnExit();
#endif // V8_SHARED
return 0;
}
@@ -1290,6 +1288,10 @@ int Shell::Main(int argc, char* argv[]) {
V8::Dispose();
+#ifndef V8_SHARED
+ OnExit();
+#endif // V8_SHARED
+
return result;
}
View
8 deps/v8/src/handles.cc
@@ -617,15 +617,17 @@ Handle<FixedArray> CalculateLineEnds(Handle<String> src,
{
AssertNoAllocation no_heap_allocation; // ensure vectors stay valid.
// Dispatch on type of strings.
- if (src->IsAsciiRepresentation()) {
+ String::FlatContent content = src->GetFlatContent();
+ ASSERT(content.IsFlat());
+ if (content.IsAscii()) {
CalculateLineEnds(isolate,
&line_ends,
- src->ToAsciiVector(),
+ content.ToAsciiVector(),
with_last_line);
} else {
CalculateLineEnds(isolate,
&line_ends,
- src->ToUC16Vector(),
+ content.ToUC16Vector(),
with_last_line);
}
}
View
23 deps/v8/src/hydrogen-instructions.cc
@@ -641,6 +641,7 @@ void HBoundsCheck::PrintDataTo(StringStream* stream) {
length()->PrintNameTo(stream);
}
+
void HCallConstantFunction::PrintDataTo(StringStream* stream) {
if (IsApplyFunction()) {
stream->Add("optimized apply ");
@@ -777,7 +778,7 @@ void HHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
void HTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
value()->PrintNameTo(stream);
stream->Add(" == ");
- stream->Add(type_literal_->ToAsciiVector());
+ stream->Add(type_literal_->GetFlatContent().ToAsciiVector());
}
@@ -875,6 +876,21 @@ Range* HValue::InferRange() {
}
+Range* HChange::InferRange() {
+ Range* input_range = value()->range();
+ if (from().IsInteger32() &&
+ to().IsTagged() &&
+ input_range != NULL && input_range->IsInSmiRange()) {
+ set_type(HType::Smi());
+ }
+ Range* result = (input_range != NULL)
+ ? input_range->Copy()
+ : HValue::InferRange();
+ if (to().IsInteger32()) result->set_can_be_minus_zero(false);
+ return result;
+}
+
+
Range* HConstant::InferRange() {
if (has_int32_value_) {
Range* result = new Range(int32_value_, int32_value_);
@@ -1220,6 +1236,7 @@ Range* HSar::InferRange() {
? left()->range()->Copy()
: new Range();
result->Sar(c->Integer32Value());
+ result->set_can_be_minus_zero(false);
return result;
}
}
@@ -1243,6 +1260,7 @@ Range* HShr::InferRange() {
? left()->range()->Copy()
: new Range();
result->Sar(c->Integer32Value());
+ result->set_can_be_minus_zero(false);
return result;
}
}
@@ -1259,6 +1277,7 @@ Range* HShl::InferRange() {
? left()->range()->Copy()
: new Range();
result->Shl(c->Integer32Value());
+ result->set_can_be_minus_zero(false);
return result;
}
}
@@ -1306,7 +1325,7 @@ void HLoadNamedField::PrintDataTo(StringStream* stream) {
HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
HValue* object,
- ZoneMapList* types,
+ SmallMapList* types,
Handle<String> name)
: types_(Min(types->length(), kMaxLoadPolymorphism)),
name_(name),
View
28 deps/v8/src/hydrogen-instructions.h
@@ -227,14 +227,20 @@ class Range: public ZoneObject {
Range* next() const { return next_; }
Range* CopyClearLower() const { return new Range(kMinInt, upper_); }
Range* CopyClearUpper() const { return new Range(lower_, kMaxInt); }
- Range* Copy() const { return new Range(lower_, upper_); }
+ Range* Copy() const {
+ Range* result = new Range(lower_, upper_);
+ result->set_can_be_minus_zero(CanBeMinusZero());
+ return result;
+ }
int32_t Mask() const;
void set_can_be_minus_zero(bool b) { can_be_minus_zero_ = b; }
bool CanBeMinusZero() const { return CanBeZero() && can_be_minus_zero_; }
bool CanBeZero() const { return upper_ >= 0 && lower_ <= 0; }
bool CanBeNegative() const { return lower_ < 0; }
bool Includes(int value) const { return lower_ <= value && upper_ >= value; }
- bool IsMostGeneric() const { return lower_ == kMinInt && upper_ == kMaxInt; }
+ bool IsMostGeneric() const {
+ return lower_ == kMinInt && upper_ == kMaxInt && CanBeMinusZero();
+ }
bool IsInSmiRange() const {
return lower_ >= Smi::kMinValue && upper_ <= Smi::kMaxValue;
}
@@ -578,9 +584,9 @@ class HValue: public ZoneObject {
virtual bool IsConvertibleToInteger() const { return true; }
HType type() const { return type_; }
- void set_type(HType type) {
- ASSERT(HasNoUses());
- type_ = type;
+ void set_type(HType new_type) {
+ ASSERT(new_type.IsSubtypeOf(type_));
+ type_ = new_type;
}
// An operation needs to override this function iff:
@@ -1100,10 +1106,6 @@ class HChange: public HUnaryOperation {
set_representation(to);
SetFlag(kUseGVN);
if (is_truncating) SetFlag(kTruncatingToInt32);
- if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
- value->range()->IsInSmiRange()) {
- set_type(HType::Smi());
- }
}
virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
@@ -1115,6 +1117,8 @@ class HChange: public HUnaryOperation {
return from_;
}
+ virtual Range* InferRange();
+
virtual void PrintDataTo(StringStream* stream);
DECLARE_CONCRETE_INSTRUCTION(Change)
@@ -3405,12 +3409,12 @@ class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
public:
HLoadNamedFieldPolymorphic(HValue* context,
HValue* object,
- ZoneMapList* types,
+ SmallMapList* types,
Handle<String> name);
HValue* context() { return OperandAt(0); }
HValue* object() { return OperandAt(1); }
- ZoneMapList* types() { return &types_; }
+ SmallMapList* types() { return &types_; }
Handle<String> name() { return name_; }
bool need_generic() { return need_generic_; }
@@ -3428,7 +3432,7 @@ class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> {
virtual bool DataEquals(HValue* value);
private:
- ZoneMapList types_;
+ SmallMapList types_;
Handle<String> name_;
bool need_generic_;
};
View
42 deps/v8/src/hydrogen.cc
@@ -2325,20 +2325,11 @@ HGraph* HGraphBuilder::CreateGraph() {
HInferRepresentation rep(graph());
rep.Analyze();
- if (FLAG_use_range) {
- HRangeAnalysis rangeAnalysis(graph());
- rangeAnalysis.Analyze();
- }
-
- graph()->InitializeInferredTypes();
- graph()->Canonicalize();
graph()->MarkDeoptimizeOnUndefined();
graph()->InsertRepresentationChanges();
- graph()->ComputeMinusZeroChecks();
- // Eliminate redundant stack checks on backwards branches.
- HStackCheckEliminator sce(graph());
- sce.Process();
+ graph()->InitializeInferredTypes();
+ graph()->Canonicalize();
// Perform common subexpression elimination and loop-invariant code motion.
if (FLAG_use_gvn) {
@@ -2347,6 +2338,16 @@ HGraph* HGraphBuilder::CreateGraph() {
gvn.Analyze();
}
+ if (FLAG_use_range) {
+ HRangeAnalysis rangeAnalysis(graph());
+ rangeAnalysis.Analyze();
+ }
+ graph()->ComputeMinusZeroChecks();
+
+ // Eliminate redundant stack checks on backwards branches.
+ HStackCheckEliminator sce(graph());
+ sce.Process();
+
// Replace the results of check instructions with the original value, if the
// result is used. This is safe now, since we don't do code motion after this
// point. It enables better register allocation since the value produced by
@@ -3395,7 +3396,7 @@ HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object,
ASSERT(!name.is_null());
LookupResult lookup;
- ZoneMapList* types = expr->GetReceiverTypes();
+ SmallMapList* types = expr->GetReceiverTypes();
bool is_monomorphic = expr->IsMonomorphic() &&
ComputeStoredField(types->first(), name, &lookup);
@@ -3409,7 +3410,7 @@ HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object,
void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr,
HValue* object,
HValue* value,
- ZoneMapList* types,
+ SmallMapList* types,
Handle<String> name) {
// TODO(ager): We should recognize when the prototype chains for different
// maps are identical. In that case we can avoid repeatedly generating the
@@ -3500,7 +3501,7 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
Handle<String> name = Handle<String>::cast(key->handle());
ASSERT(!name.is_null());
- ZoneMapList* types = expr->GetReceiverTypes();
+ SmallMapList* types = expr->GetReceiverTypes();
LookupResult lookup;
if (expr->IsMonomorphic()) {
@@ -3986,7 +3987,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
*has_side_effects = false;
AddInstruction(new(zone()) HCheckNonSmi(object));
AddInstruction(HCheckInstanceType::NewIsSpecObject(object));
- ZoneMapList* maps = prop->GetReceiverTypes();
+ SmallMapList* maps = prop->GetReceiverTypes();
bool todo_external_array = false;
static const int kNumElementTypes = JSObject::kElementsKindCount;
@@ -4260,7 +4261,7 @@ void HGraphBuilder::VisitProperty(Property* expr) {
} else if (expr->key()->IsPropertyName()) {
Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
- ZoneMapList* types = expr->GetReceiverTypes();
+ SmallMapList* types = expr->GetReceiverTypes();
HValue* obj = Pop();
if (expr->IsMonomorphic()) {
@@ -4321,7 +4322,7 @@ void HGraphBuilder::AddCheckConstantFunction(Call* expr,
void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr,
HValue* receiver,
- ZoneMapList* types,
+ SmallMapList* types,
Handle<String> name) {
// TODO(ager): We should recognize when the prototype chains for different
// maps are identical. In that case we can avoid repeatedly generating the
@@ -4849,13 +4850,14 @@ void HGraphBuilder::VisitCall(Call* expr) {
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName();
- ZoneMapList* types = expr->GetReceiverTypes();
+ SmallMapList* types = expr->GetReceiverTypes();
HValue* receiver =
environment()->ExpressionStackAt(expr->arguments()->length());
if (expr->IsMonomorphic()) {
- Handle<Map> receiver_map =
- (types == NULL) ? Handle<Map>::null() : types->first();
+ Handle<Map> receiver_map = (types == NULL || types->is_empty())
+ ? Handle<Map>::null()
+ : types->first();
if (TryInlineBuiltinFunction(expr,
receiver,
receiver_map,
View
4 deps/v8/src/hydrogen.h
@@ -901,11 +901,11 @@ class HGraphBuilder: public AstVisitor {
void HandlePolymorphicStoreNamedField(Assignment* expr,
HValue* object,
HValue* value,
- ZoneMapList* types,
+ SmallMapList* types,
Handle<String> name);
void HandlePolymorphicCallNamed(Call* expr,
HValue* receiver,
- ZoneMapList* types,
+ SmallMapList* types,
Handle<String> name);
void HandleLiteralCompareTypeof(CompareOperation* compare_expr,
Expression* expr,
View
10 deps/v8/src/interpreter-irregexp.cc
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -635,8 +635,9 @@ bool IrregexpInterpreter::Match(Isolate* isolate,
AssertNoAllocation a;
const byte* code_base = code_array->GetDataStartAddress();
uc16 previous_char = '\n';
- if (subject->IsAsciiRepresentation()) {
- Vector<const char> subject_vector = subject->ToAsciiVector();
+ String::FlatContent subject_content = subject->GetFlatContent();
+ if (subject_content.IsAscii()) {
+ Vector<const char> subject_vector = subject_content.ToAsciiVector();
if (start_position != 0) previous_char = subject_vector[start_position - 1];
return RawMatch(isolate,
code_base,
@@ -645,7 +646,8 @@ bool IrregexpInterpreter::Match(Isolate* isolate,
start_position,
previous_char);
} else {
- Vector<const uc16> subject_vector = subject->ToUC16Vector();
+ ASSERT(subject_content.IsTwoByte());
+ Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
if (start_position != 0) previous_char = subject_vector[start_position - 1];
return RawMatch(isolate,
code_base,
View
46 deps/v8/src/jsregexp.cc
@@ -212,19 +212,7 @@ static void SetAtomLastCapture(FixedArray* array,
RegExpImpl::SetCapture(array, 1, to);
}
- /* template <typename SubjectChar>, typename PatternChar>
-static int ReStringMatch(Vector<const SubjectChar> sub_vector,
- Vector<const PatternChar> pat_vector,
- int start_index) {
- int pattern_length = pat_vector.length();
- if (pattern_length == 0) return start_index;
-
- int subject_length = sub_vector.length();
- if (start_index + pattern_length > subject_length) return -1;
- return SearchString(sub_vector, pat_vector, start_index);
-}
- */
Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
Handle<String> subject,
int index,
@@ -237,35 +225,39 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
if (!subject->IsFlat()) FlattenString(subject);
AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
// Extract flattened substrings of cons strings before determining asciiness.
- String* seq_sub = *subject;
- if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first();
String* needle = String::cast(re->DataAt(JSRegExp::kAtomPatternIndex));
int needle_len = needle->length();
+ ASSERT(needle->IsFlat());
if (needle_len != 0) {
- if (index + needle_len > subject->length())
- return isolate->factory()->null_value();
+ if (index + needle_len > subject->length()) {
+ return isolate->factory()->null_value();
+ }
+ String::FlatContent needle_content = needle->GetFlatContent();
+ String::FlatContent subject_content = subject->GetFlatContent();
+ ASSERT(needle_content.IsFlat());
+ ASSERT(subject_content.IsFlat());
// dispatch on type of strings
- index = (needle->IsAsciiRepresentation()
- ? (seq_sub->IsAsciiRepresentation()
+ index = (needle_content.IsAscii()
+ ? (subject_content.IsAscii()
? SearchString(isolate,
- seq_sub->ToAsciiVector(),
- needle->ToAsciiVector(),
+ subject_content.ToAsciiVector(),
+ needle_content.ToAsciiVector(),
index)
: SearchString(isolate,
- seq_sub->ToUC16Vector(),
- needle->ToAsciiVector(),
+ subject_content.ToUC16Vector(),
+ needle_content.ToAsciiVector(),
index))
- : (seq_sub->IsAsciiRepresentation()
+ : (subject_content.IsAscii()
? SearchString(isolate,
- seq_sub->ToAsciiVector(),
- needle->ToUC16Vector(),
+ subject_content.ToAsciiVector(),
+ needle_content.ToUC16Vector(),
index)
: SearchString(isolate,
- seq_sub->ToUC16Vector(),
- needle->ToUC16Vector(),
+ subject_content.ToUC16Vector(),
+ needle_content.ToUC16Vector(),
index)));
if (index == -1) return isolate->factory()->null_value();
}
View
12 deps/v8/src/messages.js
@@ -57,11 +57,13 @@ function FormatString(format, message) {
for (var i = 0; i < format.length; i++) {
var str = format[i];
for (arg_num = 0; arg_num < kReplacementMarkers.length; arg_num++) {
- if (str !== kReplacementMarkers[arg_num]) continue;
- try {
- str = ToDetailString(args[arg_num]);
- } catch (e) {
- str = "#<error>";
+ if (str == kReplacementMarkers[arg_num]) {
+ try {
+ str = ToDetailString(args[arg_num]);
+ } catch (e) {
+ str = "#<error>";
+ }
+ break;
}
}
result += str;
View
5 deps/v8/src/objects-inl.h
@@ -297,6 +297,11 @@ StringRepresentationTag StringShape::representation_tag() {
}
+uint32_t StringShape::encoding_tag() {
+ return type_ & kStringEncodingMask;
+}
+
+
uint32_t StringShape::full_representation_tag() {
return (type_ & (kStringRepresentationMask | kStringEncodingMask));
}
View
121 deps/v8/src/objects.cc
@@ -5038,55 +5038,36 @@ int String::Utf8Length() {
}
-Vector<const char> String::ToAsciiVector() {
- ASSERT(IsAsciiRepresentation());
- ASSERT(IsFlat());
-
- int offset = 0;
+String::FlatContent String::GetFlatContent() {
int length = this->length();
- StringRepresentationTag string_tag = StringShape(this).representation_tag();
+ StringShape shape(this);
String* string = this;
- if (string_tag == kConsStringTag) {
+ if (shape.representation_tag() == kConsStringTag) {
ConsString* cons = ConsString::cast(string);
- ASSERT(cons->second()->length() == 0);
- string = cons->first();
- string_tag = StringShape(string).representation_tag();
- }
- if (string_tag == kSeqStringTag) {
- SeqAsciiString* seq = SeqAsciiString::cast(string);
- char* start = seq->GetChars();
- return Vector<const char>(start + offset, length);
- }
- ASSERT(string_tag == kExternalStringTag);
- ExternalAsciiString* ext = ExternalAsciiString::cast(string);
- const char* start = ext->resource()->data();
- return Vector<const char>(start + offset, length);
-}
-
-
-Vector<const uc16> String::ToUC16Vector() {
- ASSERT(IsTwoByteRepresentation());
- ASSERT(IsFlat());
-
- int offset = 0;
- int length = this->length();
- StringRepresentationTag string_tag = StringShape(this).representation_tag();
- String* string = this;
- if (string_tag == kConsStringTag) {
- ConsString* cons = ConsString::cast(string);
- ASSERT(cons->second()->length() == 0);
+ if (cons->second()->length() != 0) {
+ return FlatContent();
+ }
string = cons->first();
- string_tag = StringShape(string).representation_tag();
+ shape = StringShape(string);
}
- if (string_tag == kSeqStringTag) {
- SeqTwoByteString* seq = SeqTwoByteString::cast(string);
- return Vector<const uc16>(seq->GetChars() + offset, length);
+ if (shape.encoding_tag() == kAsciiStringTag) {
+ const char* start;
+ if (shape.representation_tag() == kSeqStringTag) {
+ start = SeqAsciiString::cast(string)->GetChars();
+ } else {
+ start = ExternalAsciiString::cast(string)->resource()->data();
+ }
+ return FlatContent(Vector<const char>(start, length));
+ } else {
+ ASSERT(shape.encoding_tag() == kTwoByteStringTag);
+ const uc16* start;
+ if (shape.representation_tag() == kSeqStringTag) {
+ start = SeqTwoByteString::cast(string)->GetChars();
+ } else {
+ start = ExternalTwoByteString::cast(string)->resource()->data();
+ }
+ return FlatContent(Vector<const uc16>(start, length));
}
- ASSERT(string_tag == kExternalStringTag);
- ExternalTwoByteString* ext = ExternalTwoByteString::cast(string);
- const uc16* start =
- reinterpret_cast<const uc16*>(ext->resource()->data());
- return Vector<const uc16>(start + offset, length);
}
@@ -5536,11 +5517,13 @@ void FlatStringReader::PostGarbageCollection() {
if (str_ == NULL) return;
Handle<String> str(str_);
ASSERT(str->IsFlat());
- is_ascii_ = str->IsAsciiRepresentation();
+ String::FlatContent content = str->GetFlatContent();
+ ASSERT(content.IsFlat());
+ is_ascii_ = content.IsAscii();
if (is_ascii_) {
- start_ = str->ToAsciiVector().start();
+ start_ = content.ToAsciiVector().start();
} else {
- start_ = str->ToUC16Vector().start();
+ start_ = content.ToUC16Vector().start();
}
}
@@ -5860,12 +5843,13 @@ template <typename IteratorA>
static inline bool CompareStringContentsPartial(Isolate* isolate,
IteratorA* ia,
String* b) {
- if (b->IsFlat()) {
- if (b->IsAsciiRepresentation()) {
- VectorIterator<char> ib(b->ToAsciiVector());
+ String::FlatContent content = b->GetFlatContent();
+ if (content.IsFlat()) {
+ if (content.IsAscii()) {
+ VectorIterator<char> ib(content.ToAsciiVector());
return CompareStringContents(ia, &ib);
} else {
- VectorIterator<uc16> ib(b->ToUC16Vector());
+ VectorIterator<uc16> ib(content.ToUC16Vector());
return CompareStringContents(ia, &ib);
}
} else {
@@ -5904,16 +5888,18 @@ bool String::SlowEquals(String* other) {
}
Isolate* isolate = GetIsolate();
- if (lhs->IsFlat()) {
- if (lhs->IsAsciiRepresentation()) {
- Vector<const char> vec1 = lhs->ToAsciiVector();
- if (rhs->IsFlat()) {
- if (rhs->IsAsciiRepresentation()) {
- Vector<const char> vec2 = rhs->ToAsciiVector();
+ String::FlatContent lhs_content = lhs->GetFlatContent();
+ String::FlatContent rhs_content = rhs->GetFlatContent();
+ if (lhs_content.IsFlat()) {
+ if (lhs_content.IsAscii()) {
+ Vector<const char> vec1 = lhs_content.ToAsciiVector();
+ if (rhs_content.IsFlat()) {
+ if (rhs_content.IsAscii()) {
+ Vector<const char> vec2 = rhs_content.ToAsciiVector();
return CompareRawStringContents(vec1, vec2);
} else {
VectorIterator<char> buf1(vec1);
- VectorIterator<uc16> ib(rhs->ToUC16Vector());
+ VectorIterator<uc16> ib(rhs_content.ToUC16Vector());
return CompareStringContents(&buf1, &ib);
}
} else {
@@ -5923,14 +5909,14 @@ bool String::SlowEquals(String* other) {
isolate->objects_string_compare_buffer_b());
}
} else {
- Vector<const uc16> vec1 = lhs->ToUC16Vector();
- if (rhs->IsFlat()) {
- if (rhs->IsAsciiRepresentation()) {
+ Vector<const uc16> vec1 = lhs_content.ToUC16Vector();
+ if (rhs_content.IsFlat()) {
+ if (rhs_content.IsAscii()) {
VectorIterator<uc16> buf1(vec1);
- VectorIterator<char> ib(rhs->ToAsciiVector());
+ VectorIterator<char> ib(rhs_content.ToAsciiVector());
return CompareStringContents(&buf1, &ib);
} else {
- Vector<const uc16> vec2(rhs->ToUC16Vector());
+ Vector<const uc16> vec2(rhs_content.ToUC16Vector());
return CompareRawStringContents(vec1, vec2);
}
} else {
@@ -5983,8 +5969,10 @@ bool String::IsEqualTo(Vector<const char> str) {
bool String::IsAsciiEqualTo(Vector<const char> str) {
int slen = length();
if (str.length() != slen) return false;
- if (IsFlat() && IsAsciiRepresentation()) {
- return CompareChars(ToAsciiVector().start(), str.start(), slen) == 0;
+ FlatContent content = GetFlatContent();
+ if (content.IsAscii()) {
+ return CompareChars(content.ToAsciiVector().start(),
+ str.start(), slen) == 0;
}
for (int i = 0; i < slen; i++) {
if (Get(i) != static_cast<uint16_t>(str[i])) return false;
@@ -5996,8 +5984,9 @@ bool String::IsAsciiEqualTo(Vector<const char> str) {
bool String::IsTwoByteEqualTo(Vector<const uc16> str) {
int slen = length();
if (str.length() != slen) return false;
- if (IsFlat() && IsTwoByteRepresentation()) {
- return CompareChars(ToUC16Vector().start(), str.start(), slen) == 0;
+ FlatContent content = GetFlatContent();
+ if (content.IsTwoByte()) {
+ return CompareChars(content.ToUC16Vector().start(), str.start(), slen) == 0;
}
for (int i = 0; i < slen; i++) {
if (Get(i) != str[i]) return false;
View
60 deps/v8/src/objects.h
@@ -5789,6 +5789,7 @@ class StringShape BASE_EMBEDDED {
inline bool IsSequentialTwoByte();
inline bool IsSymbol();
inline StringRepresentationTag representation_tag();
+ inline uint32_t encoding_tag();
inline uint32_t full_representation_tag();
inline uint32_t size_tag();
#ifdef DEBUG
@@ -5820,6 +5821,51 @@ class StringShape BASE_EMBEDDED {
// All string values have a length field.
class String: public HeapObject {
public:
+ // Representation of the flat content of a String.
+ // A non-flat string doesn't have flat content.
+ // A flat string has content that's encoded as a sequence of either
+ // ASCII chars or two-byte UC16.
+ // Returned by String::GetFlatContent().
+ class FlatContent {
+ public:
+ // Returns true if the string is flat and this structure contains content.
+ bool IsFlat() { return state_ != NON_FLAT; }
+ // Returns true if the structure contains ASCII content.
+ bool IsAscii() { return state_ == ASCII; }
+ // Returns true if the structure contains two-byte content.
+ bool IsTwoByte() { return state_ == TWO_BYTE; }
+
+ // Return the ASCII content of the string. Only use if IsAscii() returns
+ // true.
+ Vector<const char> ToAsciiVector() {
+ ASSERT_EQ(ASCII, state_);
+ return Vector<const char>::cast(buffer_);
+ }
+ // Return the two-byte content of the string. Only use if IsTwoByte()
+ // returns true.
+ Vector<const uc16> ToUC16Vector() {
+ ASSERT_EQ(TWO_BYTE, state_);
+ return Vector<const uc16>::cast(buffer_);
+ }
+
+ private:
+ enum State { NON_FLAT, ASCII, TWO_BYTE };
+
+ // Constructors only used by String::GetFlatContent().
+ explicit FlatContent(Vector<const char> chars)
+ : buffer_(Vector<const byte>::cast(chars)),
+ state_(ASCII) { }
+ explicit FlatContent(Vector<const uc16> chars)
+ : buffer_(Vector<const byte>::cast(chars)),
+ state_(TWO_BYTE) { }
+ FlatContent() : buffer_(), state_(NON_FLAT) { }
+
+ Vector<const byte> buffer_;
+ State state_;
+
+ friend class String;
+ };
+
// Get and set the length of the string.
inline int length();
inline void set_length(int value);
@@ -5831,10 +5877,10 @@ class String: public HeapObject {
inline bool IsAsciiRepresentation();
inline bool IsTwoByteRepresentation();
- // Returns whether this string has ascii chars, i.e. all of them can
- // be ascii encoded. This might be the case even if the string is
+ // Returns whether this string has only ASCII chars, i.e. all of them can
+ // be ASCII encoded. This might be the case even if the string is
// two-byte. Such strings may appear when the embedder prefers
- // two-byte external representations even for ascii data.
+ // two-byte external representations even for ASCII data.
//
// NOTE: this should be considered only a hint. False negatives are
// possible.
@@ -5868,8 +5914,12 @@ class String: public HeapObject {
// string.
inline String* TryFlattenGetString(PretenureFlag pretenure = NOT_TENURED);
- Vector<const char> ToAsciiVector();
- Vector<const uc16> ToUC16Vector();
+ // Tries to return the content of a flat string as a structure holding either
+ // a flat vector of char or of uc16.
+ // If the string isn't flat, and therefore doesn't have flat content, the
+ // returned structure will report so, and can't provide a vector of either
+ // kind.
+ FlatContent GetFlatContent();
// Mark the string as an undetectable object. It only applies to
// ascii and two byte string types.
View
36 deps/v8/src/profile-generator.cc
@@ -1663,7 +1663,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
} else if (object->IsJSGlobalObject()) {
const char* tag = objects_tags_.GetTag(object);
const char* name = collection_->names()->GetName(
- GetConstructorNameForHeapProfile(JSObject::cast(object)));
+ GetConstructorName(JSObject::cast(object)));
if (tag != NULL) {
name = collection_->names()->GetFormatted("%s / %s", name, tag);
}
@@ -1691,8 +1691,7 @@ HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
return AddEntry(object,
HeapEntry::kObject,
collection_->names()->GetName(
- GetConstructorNameForHeapProfile(
- JSObject::cast(object))),
+ GetConstructorName(JSObject::cast(object))),
children_count,
retainers_count);
} else if (object->IsString()) {
@@ -2101,6 +2100,31 @@ void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj,
}
+String* V8HeapExplorer::GetConstructorName(JSObject* object) {
+ if (object->IsJSFunction()) return HEAP->closure_symbol();
+ String* constructor_name = object->constructor_name();
+ if (constructor_name == HEAP->Object_symbol()) {
+ // Look up an immediate "constructor" property, if it is a function,
+ // return its name. This is for instances of binding objects, which
+ // have prototype constructor type "Object".
+ Object* constructor_prop = NULL;
+ LookupResult result;
+ object->LocalLookupRealNamedProperty(HEAP->constructor_symbol(), &result);
+ if (result.IsProperty()) {
+ constructor_prop = result.GetLazyValue();
+ }
+ if (constructor_prop->IsJSFunction()) {
+ Object* maybe_name = JSFunction::cast(constructor_prop)->shared()->name();
+ if (maybe_name->IsString()) {
+ String* name = String::cast(maybe_name);
+ if (name->length() > 0) return name;
+ }
+ }
+ }
+ return object->constructor_name();
+}
+
+
HeapEntry* V8HeapExplorer::GetEntry(Object* obj) {
if (!obj->IsHeapObject()) return NULL;
return filler_->FindOrAddEntry(obj, this);
@@ -3250,10 +3274,4 @@ void HeapSnapshotJSONSerializer::SortHashMap(
sorted_entries->Sort(SortUsingEntryValue);
}
-
-String* GetConstructorNameForHeapProfile(JSObject* object) {
- if (object->IsJSFunction()) return HEAP->closure_symbol();
- return object->constructor_name();
-}
-
} } // namespace v8::internal
View
5 deps/v8/src/profile-generator.h
@@ -921,6 +921,8 @@ class V8HeapExplorer : public HeapEntriesAllocator {
bool IterateAndExtractReferences(SnapshotFillerInterface* filler);
void TagGlobalObjects();
+ static String* GetConstructorName(JSObject* object);
+
static HeapObject* const kInternalRootObject;
private:
@@ -1119,9 +1121,6 @@ class HeapSnapshotJSONSerializer {
DISALLOW_COPY_AND_ASSIGN(HeapSnapshotJSONSerializer);
};
-
-String* GetConstructorNameForHeapProfile(JSObject* object);
-
} } // namespace v8::internal
#endif // V8_PROFILE_GENERATOR_H_
View
212 deps/v8/src/runtime.cc
@@ -2663,21 +2663,22 @@ class CompiledReplacement {
void CompiledReplacement::Compile(Handle<String> replacement,
int capture_count,
int subject_length) {
- ASSERT(replacement->IsFlat());
- if (replacement->IsAsciiRepresentation()) {
- AssertNoAllocation no_alloc;
- ParseReplacementPattern(&parts_,
- replacement->ToAsciiVector(),
- capture_count,
- subject_length);
- } else {
- ASSERT(replacement->IsTwoByteRepresentation());
+ {
AssertNoAllocation no_alloc;
-
- ParseReplacementPattern(&parts_,
- replacement->ToUC16Vector(),
- capture_count,
- subject_length);
+ String::FlatContent content = replacement->GetFlatContent();
+ ASSERT(content.IsFlat());
+ if (content.IsAscii()) {
+ ParseReplacementPattern(&parts_,
+ content.ToAsciiVector(),
+ capture_count,
+ subject_length);
+ } else {
+ ASSERT(content.IsTwoByte());
+ ParseReplacementPattern(&parts_,
+ content.ToUC16Vector(),
+ capture_count,
+ subject_length);
+ }
}
Isolate* isolate = replacement->GetIsolate();
// Find substrings of replacement string and create them as String objects.
@@ -3049,34 +3050,32 @@ int Runtime::StringMatch(Isolate* isolate,
AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
// Extract flattened substrings of cons strings before determining asciiness.
- String* seq_sub = *sub;
- if (seq_sub->IsConsString()) seq_sub = ConsString::cast(seq_sub)->first();
- String* seq_pat = *pat;
- if (seq_pat->IsConsString()) seq_pat = ConsString::cast(seq_pat)->first();
+ String::FlatContent seq_sub = sub->GetFlatContent();
+ String::FlatContent seq_pat = pat->GetFlatContent();
// dispatch on type of strings
- if (seq_pat->IsAsciiRepresentation()) {
- Vector<const char> pat_vector = seq_pat->ToAsciiVector();
- if (seq_sub->IsAsciiRepresentation()) {
+ if (seq_pat.IsAscii()) {
+ Vector<const char> pat_vector = seq_pat.ToAsciiVector();
+ if (seq_sub.IsAscii()) {
return SearchString(isolate,
- seq_sub->ToAsciiVector(),
+ seq_sub.ToAsciiVector(),
pat_vector,
start_index);
}
return SearchString(isolate,
- seq_sub->ToUC16Vector(),
+ seq_sub.ToUC16Vector(),
pat_vector,
start_index);
}
- Vector<const uc16> pat_vector = seq_pat->ToUC16Vector();
- if (seq_sub->IsAsciiRepresentation()) {
+ Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
+ if (seq_sub.IsAscii()) {
return SearchString(isolate,
- seq_sub->ToAsciiVector(),
+ seq_sub.ToAsciiVector(),
pat_vector,
start_index);
}
return SearchString(isolate,
- seq_sub->ToUC16Vector(),
+ seq_sub.ToUC16Vector(),
pat_vector,
start_index);
}
@@ -3159,29 +3158,31 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringLastIndexOf) {
if (!sub->IsFlat()) FlattenString(sub);
if (!pat->IsFlat()) FlattenString(pat);
+ int position = -1;
AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
- int position = -1;
+ String::FlatContent sub_content = sub->GetFlatContent();
+ String::FlatContent pat_content = pat->GetFlatContent();
- if (pat->IsAsciiRepresentation()) {
- Vector<const char> pat_vector = pat->ToAsciiVector();
- if (sub->IsAsciiRepresentation()) {
- position = StringMatchBackwards(sub->ToAsciiVector(),
+ if (pat_content.IsAscii()) {
+ Vector<const char> pat_vector = pat_content.ToAsciiVector();
+ if (sub_content.IsAscii()) {
+ position = StringMatchBackwards(sub_content.ToAsciiVector(),
pat_vector,
start_index);
} else {
- position = StringMatchBackwards(sub->ToUC16Vector(),
+ position = StringMatchBackwards(sub_content.ToUC16Vector(),
pat_vector,
start_index);
}
} else {
- Vector<const uc16> pat_vector = pat->ToUC16Vector();
- if (sub->IsAsciiRepresentation()) {
- position = StringMatchBackwards(sub->ToAsciiVector(),
+ Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
+ if (sub_content.IsAscii()) {
+ position = StringMatchBackwards(sub_content.ToAsciiVector(),
pat_vector,
start_index);
} else {
- position = StringMatchBackwards(sub->ToUC16Vector(),
+ position = StringMatchBackwards(sub_content.ToUC16Vector(),
pat_vector,
start_index);
}
@@ -3399,36 +3400,38 @@ static bool SearchStringMultiple(Isolate* isolate,
for (;;) { // Break when search complete.
builder->EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
AssertNoAllocation no_gc;
- if (subject->IsAsciiRepresentation()) {
- Vector<const char> subject_vector = subject->ToAsciiVector();
- if (pattern->IsAsciiRepresentation()) {
+ String::FlatContent subject_content = subject->GetFlatContent();
+ String::FlatContent pattern_content = pattern->GetFlatContent();
+ if (subject_content.IsAscii()) {
+ Vector<const char> subject_vector = subject_content.ToAsciiVector();
+ if (pattern_content.IsAscii()) {
if (SearchStringMultiple(isolate,
subject_vector,
- pattern->ToAsciiVector(),
+ pattern_content.ToAsciiVector(),
*pattern,
builder,
&match_pos)) break;
} else {
if (SearchStringMultiple(isolate,
subject_vector,
- pattern->ToUC16Vector(),
+ pattern_content.ToUC16Vector(),
*pattern,
builder,
&match_pos)) break;
}
} else {
- Vector<const uc16> subject_vector = subject->ToUC16Vector();
- if (pattern->IsAsciiRepresentation()) {
+ Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
+ if (pattern_content.IsAscii()) {
if (SearchStringMultiple(isolate,
subject_vector,
- pattern->ToAsciiVector(),
+ pattern_content.ToAsciiVector(),
*pattern,
builder,
&match_pos)) break;
} else {
if (SearchStringMultiple(isolate,
subject_vector,
- pattern->ToUC16Vector(),
+ pattern_content.ToUC16Vector(),
*pattern,
builder,
&match_pos)) break;
@@ -5416,12 +5419,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONString) {
str = String::cast(flat);
ASSERT(str->IsFlat());
}
- if (str->IsTwoByteRepresentation()) {
+ String::FlatContent flat = str->GetFlatContent();
+ ASSERT(flat.IsFlat());
+ if (flat.IsTwoByte()) {
return QuoteJsonString<uc16, SeqTwoByteString, false>(isolate,
- str->ToUC16Vector());
+ flat.ToUC16Vector());
} else {
return QuoteJsonString<char, SeqAsciiString, false>(isolate,
- str->ToAsciiVector());
+ flat.ToAsciiVector());
}
}
@@ -5438,12 +5443,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringComma) {
str = String::cast(flat);
ASSERT(str->IsFlat());
}
- if (str->IsTwoByteRepresentation()) {
+ String::FlatContent flat = str->GetFlatContent();
+ if (flat.IsTwoByte()) {
return QuoteJsonString<uc16, SeqTwoByteString, true>(isolate,
- str->ToUC16Vector());
+ flat.ToUC16Vector());
} else {
return QuoteJsonString<char, SeqAsciiString, true>(isolate,
- str->ToAsciiVector());
+ flat.ToAsciiVector());
}
}
@@ -5478,14 +5484,16 @@ static MaybeObject* QuoteJsonStringArray(Isolate* isolate,
for (int i = 0; i < length; i++) {
if (i != 0) *(write_cursor++) = ',';
String* str = String::cast(array->get(i));
- if (str->IsTwoByteRepresentation()) {
+ String::FlatContent content = str->GetFlatContent();
+ ASSERT(content.IsFlat());
+ if (content.IsTwoByte()) {
write_cursor = WriteQuoteJsonString<Char, uc16>(isolate,
write_cursor,
- str->ToUC16Vector());
+ content.ToUC16Vector());
} else {
write_cursor = WriteQuoteJsonString<Char, char>(isolate,
write_cursor,
- str->ToAsciiVector());
+ content.ToAsciiVector());
}
}
*(write_cursor++) = ']';
@@ -5964,11 +5972,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
// No allocation block.
{
- AssertNoAllocation nogc;
- if (subject->IsAsciiRepresentation()) {
- Vector<const char> subject_vector = subject->ToAsciiVector();
- if (pattern->IsAsciiRepresentation()) {
- Vector<const char> pattern_vector = pattern->ToAsciiVector();
+ AssertNoAllocation no_gc;
+ String::FlatContent subject_content = subject->GetFlatContent();
+ String::FlatContent pattern_content = pattern->GetFlatContent();
+ ASSERT(subject_content.IsFlat());
+ ASSERT(pattern_content.IsFlat());
+ if (subject_content.IsAscii()) {
+ Vector<const char> subject_vector = subject_content.ToAsciiVector();
+ if (pattern_content.IsAscii()) {
+ Vector<const char> pattern_vector = pattern_content.ToAsciiVector();
if (pattern_vector.length() == 1) {
FindAsciiStringIndices(subject_vector,
pattern_vector[0],
@@ -5984,22 +5996,22 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) {
} else {
FindStringIndices(isolate,
subject_vector,
- pattern->ToUC16Vector(),
+ pattern_content.ToUC16Vector(),
&indices,
limit);
}
} else {
- Vector<const uc16> subject_vector = subject->ToUC16Vector();
+ Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
if (pattern->IsAsciiRepresentation()) {
FindStringIndices(isolate,
subject_vector,
- pattern->ToAsciiVector(),
+ pattern_content.ToAsciiVector(),
&indices,
limit);
} else {
FindStringIndices(isolate,
subject_vector,
- pattern->ToUC16Vector(),
+ pattern_content.ToUC16Vector(),
&indices,
limit);
}
@@ -6048,7 +6060,7 @@ static int CopyCachedAsciiCharsToArray(Heap* heap,
const char* chars,
FixedArray* elements,
int length) {
- AssertNoAllocation nogc;
+ AssertNoAllocation no_gc;
FixedArray* ascii_cache = heap->single_character_string_cache();
Object* undefined = heap->undefined_value();
int i;
@@ -6081,36 +6093,39 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringToArray) {
CONVERT_ARG_CHECKED(String, s, 0);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
- s->TryFlatten();
+ s = FlattenGetString(s);
const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
Handle<FixedArray> elements;
+ int position = 0;
if (s->IsFlat() && s->IsAsciiRepresentation()) {
+ // Try using cached chars where possible.
Object* obj;
{ MaybeObject* maybe_obj =
isolate->heap()->AllocateUninitializedFixedArray(length);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
elements = Handle<FixedArray>(FixedArray::cast(obj), isolate);
-
- Vector<const char> chars = s->ToAsciiVector();
- // Note, this will initialize all elements (not only the prefix)
- // to prevent GC from seeing partially initialized array.
- int num_copied_from_cache = CopyCachedAsciiCharsToArray(isolate->heap(),
- chars.start(),
- *elements,
- length);
-
- for (int i = num_copied_from_cache; i < length; ++i) {
- Handle<Object> str = LookupSingleCharacterStringFromCode(chars[i]);
- elements->set(i, *str);
+ String::FlatContent content = s->GetFlatContent();
+ if (content.IsAscii()) {
+ Vector<const char> chars = content.ToAsciiVector();
+ // Note, this will initialize all elements (not only the prefix)
+ // to prevent GC from seeing partially initialized array.
+ position = CopyCachedAsciiCharsToArray(isolate->heap(),
+ chars.start(),
+ *elements,
+ length);
+ } else {
+ MemsetPointer(elements->data_start(),
+ isolate->heap()->undefined_value(),
+ length);
}
} else {
elements = isolate->factory()->NewFixedArray(length);
- for (int i = 0; i < length; ++i) {
- Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i));
- elements->set(i, *str);
- }
+ }
+ for (int i = position; i < length; ++i) {
+ Handle<Object> str = LookupSingleCharacterStringFromCode(s->Get(i));
+ elements->set(i, *str);
}
#ifdef DEBUG
@@ -6921,22 +6936,24 @@ static Object* FlatStringCompare(String* x, String* y) {
equal_prefix_result = Smi::FromInt(LESS);
}
int r;
- if (x->IsAsciiRepresentation()) {
- Vector<const char> x_chars = x->ToAsciiVector();
- if (y->IsAsciiRepresentation()) {
- Vector<const char> y_chars = y->ToAsciiVector();
+ String::FlatContent x_content = x->GetFlatContent();
+ String::FlatContent y_content = y->GetFlatContent();
+ if (x_content.IsAscii()) {
+ Vector<const char> x_chars = x_content.ToAsciiVector();
+ if (y_content.IsAscii()) {
+ Vector<const char> y_chars = y_content.ToAsciiVector();
r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
} else {
- Vector<const uc16> y_chars = y->ToUC16Vector();
+ Vector<const uc16> y_chars = y_content.ToUC16Vector();
r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
}
} else {
- Vector<const uc16> x_chars = x->ToUC16Vector();
- if (y->IsAsciiRepresentation()) {
- Vector<const char> y_chars = y->ToAsciiVector();
+ Vector<const uc16> x_chars = x_content.ToUC16Vector();
+ if (y_content.IsAscii()) {
+ Vector<const char> y_chars = y_content.ToAsciiVector();
r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
} else {
- Vector<const uc16> y_chars = y->ToUC16Vector();
+ Vector<const uc16> y_chars = y_content.ToUC16Vector();
r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
}
}
@@ -8817,13 +8834,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) {
FixedArray* output_array = FixedArray::cast(output->elements());
RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
bool result;
- if (str->IsAsciiRepresentation()) {
- result = DateParser::Parse(str->ToAsciiVector(),
+ String::FlatContent str_content = str->GetFlatContent();
+ if (str_content.IsAscii()) {
+ result = DateParser::Parse(str_content.ToAsciiVector(),
output_array,
isolate->unicode_cache());
} else {
- ASSERT(str->IsTwoByteRepresentation());
- result = DateParser::Parse(str->ToUC16Vector(),
+ ASSERT(str_content.IsTwoByte());
+ result = DateParser::Parse(str_content.ToUC16Vector(),
output_array,
isolate->unicode_cache());
}
@@ -12803,7 +12821,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) {
ASSERT(args.length() == 2);
CONVERT_CHECKED(String, format, args[0]);
CONVERT_CHECKED(JSArray, elms, args[1]);
- Vector<const char> chars = format->ToAsciiVector();
+ String::FlatContent format_content = format->GetFlatContent();
+ RUNTIME_ASSERT(format_content.IsAscii());
+ Vector<const char> chars = format_content.ToAsciiVector();
LOGGER->LogRuntime(chars, elms);
return isolate->heap()->undefined_value();
}
View
0  deps/v8/src/scanner.cc 100755 → 100644
File mode changed
View
25 deps/v8/src/small-pointer-list.h
@@ -44,6 +44,31 @@ class SmallPointerList {
public:
SmallPointerList() : data_(kEmptyTag) {}
+ explicit SmallPointerList(int capacity) : data_(kEmptyTag) {
+ Reserve(capacity);
+ }
+
+ void Reserve(int capacity) {
+ if (capacity < 2) return;
+ if ((data_ & kTagMask) == kListTag) {
+ if (list()->capacity() >= capacity) return;
+ int old_length = list()->length();
+ list()->AddBlock(NULL, capacity - list()->capacity());
+ list()->Rewind(old_length);
+ return;
+ }
+ PointerList* list = new PointerList(capacity);
+ if ((data_ & kTagMask) == kSingletonTag) {
+ list->Add(single_value());
+ }
+ ASSERT(IsAligned(reinterpret_cast<intptr_t>(list), kPointerAlignment));
+ data_ = reinterpret_cast<intptr_t>(list) | kListTag;
+ }
+
+ void Clear() {
+ data_ = kEmptyTag;
+ }
+
bool is_empty() const { return length() == 0; }
int length() const {
View
2  deps/v8/src/string.js
@@ -149,7 +149,7 @@ function StringLastIndexOf(pat /* position */) { // length == 1
position = 0;
}
if (position + patLength < subLength) {
- index = position
+ index = position;
}
}
}
View
3  deps/v8/src/stub-cache.cc
@@ -29,6 +29,7 @@
#include "api.h"
#include "arguments.h"
+#include "ast.h"
#include "code-stubs.h"
#include "gdb-jit.h"
#include "ic-inl.h"
@@ -1161,7 +1162,7 @@ void StubCache::Clear() {
}
-void StubCache::CollectMatchingMaps(ZoneMapList* types,
+void StubCache::CollectMatchingMaps(SmallMapList* types,
String* name,
Code::Flags flags) {
for (int i = 0; i < kPrimaryTableSize; i++) {
View
4 deps/v8/src/stub-cache.h
@@ -46,8 +46,10 @@ namespace internal {
// invalidate the cache whenever a prototype map is changed. The stub
// validates the map chain as in the mono-morphic case.
+class SmallMapList;
class StubCache;
+
class SCTableReference {
public:
Address address() const { return address_; }
@@ -294,7 +296,7 @@ class StubCache {
void Clear();
// Collect all maps that match the name and flags.
- void CollectMatchingMaps(ZoneMapList* types,
+ void CollectMatchingMaps(SmallMapList* types,
String* name,
Code::Flags flags);
View
45 deps/v8/src/type-info.cc
@@ -159,23 +159,26 @@ Handle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) {
}
-ZoneMapList* TypeFeedbackOracle::LoadReceiverTypes(Property* expr,
- Handle<String> name) {
+void TypeFeedbackOracle::LoadReceiverTypes(Property* expr,
+ Handle<String> name,
+ SmallMapList* types) {
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL);
- return CollectReceiverTypes(expr->id(), name, flags);
+ CollectReceiverTypes(expr->id(), name, flags, types);
}
-ZoneMapList* TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr,
- Handle<String> name) {
+void TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr,
+ Handle<String> name,
+ SmallMapList* types) {
Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL);
- return CollectReceiverTypes(expr->id(), name, flags);
+ CollectReceiverTypes(expr->id(), name, flags, types);
}
-ZoneMapList* TypeFeedbackOracle::CallReceiverTypes(Call* expr,
- Handle<String> name,
- CallKind call_kind) {
+void TypeFeedbackOracle::CallReceiverTypes(Call* expr,
+ Handle<String> name,
+ CallKind call_kind,
+ SmallMapList* types) {
int arity = expr->arguments()->length();
// Note: Currently we do not take string extra ic data into account
@@ -189,7 +192,7 @@ ZoneMapList* TypeFeedbackOracle::CallReceiverTypes(Call* expr,
OWN_MAP,
NOT_IN_LOOP,
arity);
- return CollectReceiverTypes(expr->id(), name, flags);
+ CollectReceiverTypes(expr->id(), name, flags, types);
}
@@ -391,36 +394,30 @@ TypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) {
}
-ZoneMapList* TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
- Handle<String> name,
- Code::Flags flags) {
+void TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id,
+ Handle<String> name,
+ Code::Flags flags,
+ SmallMapList* types) {
Isolate* isolate = Isolate::Current();
Handle<Object> object = GetInfo(ast_id);
- if (object->IsUndefined() || object->IsSmi()) return NULL;
+ if (object->IsUndefined() || object->IsSmi()) return;
if (*object == isolate->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) {
// TODO(fschneider): We could collect the maps and signal that
// we need a generic store (or load) here.
ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC);
- return NULL;
} else if (object->IsMap()) {
- ZoneMapList* types = new ZoneMapList(1);
types->Add(Handle<Map>::cast(object));
- return types;
} else if (Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) {
- ZoneMapList* types = new ZoneMapList(4);
+ types->Reserve(4);
ASSERT(object->IsCode());
isolate->stub_cache()->CollectMatchingMaps(types, *name, flags);
- return types->length() > 0 ? types : NULL;
- } else {
- return NULL;
}
}
-void TypeFeedbackOracle::CollectKeyedReceiverTypes(
- unsigned ast_id,
- ZoneMapList* types) {
+void TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id,
+ SmallMapList* types) {
Handle<Object> object = GetInfo(ast_id);
if (!object->IsCode()) return;
Handle<Code> code = Handle<Code>::cast(object);
View
32 deps/v8/src/type-info.h
@@ -203,14 +203,16 @@ enum StringStubFeedback {
// Forward declarations.
class Assignment;
-class UnaryOperation;
class BinaryOperation;
class Call;
+class CaseClause;
class CompareOperation;
-class CountOperation;
class CompilationInfo;
+class CountOperation;
class Property;
-class CaseClause;
+class SmallMapList;
+class UnaryOperation;
+
class TypeFeedbackOracle BASE_EMBEDDED {
public:
@@ -225,13 +227,18 @@ class TypeFeedbackOracle BASE_EMBEDDED {
Handle<Map> LoadMonomorphicReceiverType(Property* expr);
Handle<Map> StoreMonomorphicReceiverType(Expression* expr);
- ZoneMapList* LoadReceiverTypes(Property* expr, Handle<String> name);
- ZoneMapList* StoreReceiverTypes(Assignment* expr, Handle<String> name);
- ZoneMapList* CallReceiverTypes(Call* expr,