| Index: src/heap.cc
|
| ===================================================================
|
| --- src/heap.cc (revision 766)
|
| +++ src/heap.cc (working copy)
|
| @@ -84,6 +84,8 @@
|
| GCCallback Heap::global_gc_prologue_callback_ = NULL;
|
| GCCallback Heap::global_gc_epilogue_callback_ = NULL;
|
|
|
| +ExternalSymbolCallback Heap::global_external_symbol_callback_ = NULL;
|
| +
|
| // Variables set based on semispace_size_ and old_generation_size_ in
|
| // ConfigureHeap.
|
| int Heap::young_generation_size_ = 0; // Will be 2 * semispace_size_.
|
| @@ -1535,6 +1537,29 @@
|
| }
|
|
|
|
|
| +Object* Heap::AllocateExternalSymbolFromTwoByte(
|
| + ExternalTwoByteString::Resource* resource) {
|
| + Map* map;
|
| + int length = resource->length();
|
| + if (length <= String::kMaxShortStringSize) {
|
| + map = short_external_symbol_map();
|
| + } else if (length <= String::kMaxMediumStringSize) {
|
| + map = medium_external_symbol_map();
|
| + } else {
|
| + map = long_external_symbol_map();
|
| + }
|
| +
|
| + Object* result = Allocate(map, OLD_DATA_SPACE);
|
| + if (result->IsFailure()) return result;
|
| +
|
| + ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result);
|
| + external_string->set_length(length);
|
| + external_string->set_resource(resource);
|
| +
|
| + return result;
|
| +}
|
| +
|
| +
|
| Object* Heap::LookupSingleCharacterStringFromCode(uint16_t code) {
|
| if (code <= String::kMaxAsciiCharCode) {
|
| Object* value = Heap::single_character_string_cache()->get(code);
|
| @@ -2028,9 +2053,9 @@
|
| }
|
|
|
|
|
| -Object* Heap::AllocateSymbol(unibrow::CharacterStream* buffer,
|
| - int chars,
|
| - uint32_t length_field) {
|
| +Object* Heap::AllocateInternalSymbol(unibrow::CharacterStream* buffer,
|
| + int chars,
|
| + uint32_t length_field) {
|
| // Ensure the chars matches the number of characters in the buffer.
|
| ASSERT(static_cast<unsigned>(chars) == buffer->Length());
|
| // Determine whether the string is ascii.
|
| @@ -2086,6 +2111,42 @@
|
| }
|
|
|
|
|
| +// External string resource that only contains a length field. These
|
| +// are used temporarily when allocating external symbols.
|
| +class DummyExternalStringResource
|
| + : public v8::String::ExternalStringResource {
|
| + public:
|
| + explicit DummyExternalStringResource(size_t length) : length_(length) { }
|
| +
|
| + virtual const uint16_t* data() const {
|
| + UNREACHABLE();
|
| + return NULL;
|
| + }
|
| +
|
| + virtual size_t length() const { return length_; }
|
| + private:
|
| + size_t length_;
|
| +};
|
| +
|
| +
|
| +Object* Heap::AllocateExternalSymbol(Vector<const char> string, int chars) {
|
| + // Attempt to allocate the resulting external string first. Use a
|
| + // dummy string resource that has the correct length so that we only
|
| + // have to patch the external string resource after the callback.
|
| + DummyExternalStringResource dummy_resource(chars);
|
| + Object* obj = AllocateExternalSymbolFromTwoByte(&dummy_resource);
|
| + if (obj->IsFailure()) return obj;
|
| + // Perform callback.
|
| + v8::String::ExternalStringResource* resource =
|
| + global_external_symbol_callback_(string.start(), string.length());
|
| + // Patch the resource pointer of the result.
|
| + ExternalTwoByteString* result = ExternalTwoByteString::cast(obj);
|
| + result->set_resource(resource);
|
| + ASSERT(result->IsEqualTo(string));
|
| + return result;
|
| +}
|
| +
|
| +
|
| Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) {
|
| AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
|
| int size = SeqAsciiString::SizeFor(length);
|
|
|