Add runtime function for string to array conversion.
Review URL: http://codereview.chromium.org/669060 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4022 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8c086c50dd
commit
05a74e8131
@ -242,16 +242,6 @@ BUILTIN(ArrayCodeGeneric) {
|
||||
}
|
||||
|
||||
|
||||
static Object* AllocateUninitializedFixedArray(int len) {
|
||||
Object* obj = Heap::AllocateRawFixedArray(len);
|
||||
if (obj->IsFailure()) return obj;
|
||||
|
||||
reinterpret_cast<FixedArray*>(obj)->set_map(Heap::fixed_array_map());
|
||||
FixedArray::cast(obj)->set_length(len);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
static Object* AllocateJSArray() {
|
||||
JSFunction* array_function =
|
||||
Top::context()->global_context()->array_function();
|
||||
@ -363,7 +353,7 @@ BUILTIN(ArrayPush) {
|
||||
if (new_length > elms->length()) {
|
||||
// New backing storage is needed.
|
||||
int capacity = new_length + (new_length >> 1) + 16;
|
||||
Object* obj = AllocateUninitializedFixedArray(capacity);
|
||||
Object* obj = Heap::AllocateUninitializedFixedArray(capacity);
|
||||
if (obj->IsFailure()) return obj;
|
||||
FixedArray* new_elms = FixedArray::cast(obj);
|
||||
|
||||
@ -473,7 +463,7 @@ BUILTIN(ArrayUnshift) {
|
||||
if (new_length > elms->length()) {
|
||||
// New backing storage is needed.
|
||||
int capacity = new_length + (new_length >> 1) + 16;
|
||||
Object* obj = AllocateUninitializedFixedArray(capacity);
|
||||
Object* obj = Heap::AllocateUninitializedFixedArray(capacity);
|
||||
if (obj->IsFailure()) return obj;
|
||||
FixedArray* new_elms = FixedArray::cast(obj);
|
||||
|
||||
@ -553,7 +543,7 @@ BUILTIN(ArraySlice) {
|
||||
if (result->IsFailure()) return result;
|
||||
JSArray* result_array = JSArray::cast(result);
|
||||
|
||||
result = AllocateUninitializedFixedArray(result_len);
|
||||
result = Heap::AllocateUninitializedFixedArray(result_len);
|
||||
if (result->IsFailure()) return result;
|
||||
FixedArray* result_elms = FixedArray::cast(result);
|
||||
|
||||
@ -622,7 +612,7 @@ BUILTIN(ArraySplice) {
|
||||
if (result->IsFailure()) return result;
|
||||
JSArray* result_array = JSArray::cast(result);
|
||||
|
||||
result = AllocateUninitializedFixedArray(actualDeleteCount);
|
||||
result = Heap::AllocateUninitializedFixedArray(actualDeleteCount);
|
||||
if (result->IsFailure()) return result;
|
||||
FixedArray* result_elms = FixedArray::cast(result);
|
||||
|
||||
@ -660,7 +650,7 @@ BUILTIN(ArraySplice) {
|
||||
if (new_length > elms->length()) {
|
||||
// New backing storage is needed.
|
||||
int capacity = new_length + (new_length >> 1) + 16;
|
||||
Object* obj = AllocateUninitializedFixedArray(capacity);
|
||||
Object* obj = Heap::AllocateUninitializedFixedArray(capacity);
|
||||
if (obj->IsFailure()) return obj;
|
||||
FixedArray* new_elms = FixedArray::cast(obj);
|
||||
|
||||
|
@ -43,6 +43,12 @@ Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) {
|
||||
}
|
||||
|
||||
|
||||
Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) {
|
||||
ASSERT(0 <= size);
|
||||
CALL_HEAP_FUNCTION(Heap::AllocateUninitializedFixedArray(size), FixedArray);
|
||||
}
|
||||
|
||||
|
||||
Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size) {
|
||||
ASSERT(0 <= size);
|
||||
CALL_HEAP_FUNCTION(Heap::AllocateFixedArrayWithHoles(size), FixedArray);
|
||||
|
@ -45,6 +45,10 @@ class Factory : public AllStatic {
|
||||
int size,
|
||||
PretenureFlag pretenure = NOT_TENURED);
|
||||
|
||||
// Allocate a new uninitialized fixed array. It must be filled by
|
||||
// the caller.
|
||||
static Handle<FixedArray> NewUninitializedFixedArray(int size);
|
||||
|
||||
// Allocate a new fixed array with non-existing entries (the hole).
|
||||
static Handle<FixedArray> NewFixedArrayWithHoles(int size);
|
||||
|
||||
|
12
src/heap.cc
12
src/heap.cc
@ -2967,6 +2967,18 @@ Object* Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
|
||||
}
|
||||
|
||||
|
||||
Object* Heap::AllocateUninitializedFixedArray(int length) {
|
||||
if (length == 0) return empty_fixed_array();
|
||||
|
||||
Object* obj = AllocateRawFixedArray(length);
|
||||
if (obj->IsFailure()) return obj;
|
||||
|
||||
reinterpret_cast<FixedArray*>(obj)->set_map(fixed_array_map());
|
||||
FixedArray::cast(obj)->set_length(length);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
Object* Heap::AllocateFixedArrayWithHoles(int length) {
|
||||
if (length == 0) return empty_fixed_array();
|
||||
Object* result = AllocateRawFixedArray(length);
|
||||
|
@ -450,9 +450,16 @@ class Heap : public AllStatic {
|
||||
// failed.
|
||||
// Please note this does not perform a garbage collection.
|
||||
static Object* AllocateFixedArray(int length, PretenureFlag pretenure);
|
||||
// Allocate uninitialized, non-tenured fixed array with length elements.
|
||||
// Allocates a fixed array initialized with undefined values
|
||||
static Object* AllocateFixedArray(int length);
|
||||
|
||||
// Allocates an uninitialized fixed array. It must be filled by the caller.
|
||||
//
|
||||
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
|
||||
// failed.
|
||||
// Please note this does not perform a garbage collection.
|
||||
static Object* AllocateUninitializedFixedArray(int length);
|
||||
|
||||
// Make a copy of src and return it. Returns
|
||||
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
|
||||
static Object* CopyFixedArray(FixedArray* src);
|
||||
|
@ -4213,6 +4213,70 @@ static Object* Runtime_StringTrim(Arguments args) {
|
||||
return s->SubString(left, right);
|
||||
}
|
||||
|
||||
|
||||
// Copies ascii characters to the given fixed array looking up
|
||||
// one-char strings in the cache. Gives up on the first char that is
|
||||
// not in the cache. Returns the length of the successfully copied
|
||||
// prefix.
|
||||
static int CopyCachedAsciiCharsToArray(const char* chars,
|
||||
FixedArray* elements,
|
||||
int length) {
|
||||
AssertNoAllocation nogc;
|
||||
FixedArray* ascii_cache = Heap::single_character_string_cache();
|
||||
Object* undefined = Heap::undefined_value();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
Object* value = ascii_cache->get(chars[i]);
|
||||
if (value == undefined) return i;
|
||||
ASSERT(!Heap::InNewSpace(value));
|
||||
elements->set(i, value, SKIP_WRITE_BARRIER);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
// Converts a String to JSArray.
|
||||
// For example, "foo" => ["f", "o", "o"].
|
||||
static Object* Runtime_StringToArray(Arguments args) {
|
||||
HandleScope scope;
|
||||
ASSERT(args.length() == 1);
|
||||
CONVERT_ARG_CHECKED(String, s, 0);
|
||||
|
||||
s->TryFlatten();
|
||||
const int length = s->length();
|
||||
|
||||
Handle<FixedArray> elements = Factory::NewUninitializedFixedArray(length);
|
||||
if (s->IsFlat()) {
|
||||
if (s->IsAsciiRepresentation()) {
|
||||
Vector<const char> chars = s->ToAsciiVector();
|
||||
int num_copied_from_cache = CopyCachedAsciiCharsToArray(chars.start(),
|
||||
*elements,
|
||||
length);
|
||||
for (int i = num_copied_from_cache; i < length; ++i) {
|
||||
elements->set(i, *LookupSingleCharacterStringFromCode(chars[i]));
|
||||
}
|
||||
} else {
|
||||
ASSERT(s->IsTwoByteRepresentation());
|
||||
Vector<const uc16> chars = s->ToUC16Vector();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
elements->set(i, *LookupSingleCharacterStringFromCode(chars[i]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
elements->set(i, *LookupSingleCharacterStringFromCode(s->Get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (int i = 0; i < length; ++i) {
|
||||
ASSERT(String::cast(elements->get(i))->length() == 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return *Factory::NewJSArrayWithElements(elements);
|
||||
}
|
||||
|
||||
|
||||
bool Runtime::IsUpperCaseChar(uint16_t ch) {
|
||||
unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
|
||||
int char_length = to_upper_mapping.get(ch, 0, chars);
|
||||
|
@ -163,6 +163,7 @@ namespace internal {
|
||||
F(StringReplaceRegExpWithString, 4, 1) \
|
||||
F(StringMatch, 3, 1) \
|
||||
F(StringTrim, 3, 1) \
|
||||
F(StringToArray, 1, 1) \
|
||||
\
|
||||
/* Numbers */ \
|
||||
F(NumberToRadixString, 2, 1) \
|
||||
|
@ -530,11 +530,7 @@ function StringSplit(separator, limit) {
|
||||
var separator_length = separator.length;
|
||||
|
||||
// If the separator string is empty then return the elements in the subject.
|
||||
if (separator_length === 0) {
|
||||
var result = $Array(length);
|
||||
for (var i = 0; i < length; i++) result[i] = subject[i];
|
||||
return result;
|
||||
}
|
||||
if (separator_length === 0) return %StringToArray(subject);
|
||||
|
||||
var result = [];
|
||||
var start_index = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user