Skip to content

Commit

Permalink
Keep natives source code in external strings instead of putting
Browse files Browse the repository at this point in the history
it in regular flat strings that are part of the snapshot.
After this change we don't need libraries-empty.cc any more.  In
this change libraries-empty.cc is just a the same as libraries.cc
and the scons build builds it but does not use it.  We can move
in stages to a situation where it is not generated at all for all
the build systems that we have.
Review URL: http://codereview.chromium.org/360050

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3238 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
  • Loading branch information
[email protected] committed Nov 6, 2009
1 parent 321bed2 commit 6a3921f
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 27 deletions.
1 change: 0 additions & 1 deletion src/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ def ConfigureObjectFiles():
else:
snapshot_cc = Command('snapshot.cc', [], [])
snapshot_obj = context.ConfigureObject(env, snapshot_cc, CPPPATH=['.'])
libraries_obj = context.ConfigureObject(env, libraries_empty_src, CPPPATH=['.'])
else:
snapshot_obj = empty_snapshot_obj
library_objs = [non_snapshot_files, libraries_obj, snapshot_obj]
Expand Down
37 changes: 34 additions & 3 deletions src/bootstrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "global-handles.h"
#include "macro-assembler.h"
#include "natives.h"
#include "snapshot.h"

namespace v8 {
namespace internal {
Expand Down Expand Up @@ -92,14 +93,34 @@ class SourceCodeCache BASE_EMBEDDED {

static SourceCodeCache natives_cache(Script::TYPE_NATIVE);
static SourceCodeCache extensions_cache(Script::TYPE_EXTENSION);
// This is for delete, not delete[].
static List<char*>* delete_these_non_arrays_on_tear_down = NULL;


Handle<String> Bootstrapper::NativesSourceLookup(int index) {
ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
if (Heap::natives_source_cache()->get(index)->IsUndefined()) {
Handle<String> source_code =
Factory::NewStringFromAscii(Natives::GetScriptSource(index));
Heap::natives_source_cache()->set(index, *source_code);
if (!Snapshot::IsEnabled || FLAG_new_snapshot) {
if (delete_these_non_arrays_on_tear_down == NULL) {
delete_these_non_arrays_on_tear_down = new List<char*>(2);
}
// We can use external strings for the natives.
NativesExternalStringResource* resource =
new NativesExternalStringResource(
Natives::GetScriptSource(index).start());
// The resources are small objects and we only make a fixed number of
// them, but lets clean them up on exit for neatness.
delete_these_non_arrays_on_tear_down->
Add(reinterpret_cast<char*>(resource));
Handle<String> source_code =
Factory::NewExternalStringFromAscii(resource);
Heap::natives_source_cache()->set(index, *source_code);
} else {
// Old snapshot code can't cope with external strings at all.
Handle<String> source_code =
Factory::NewStringFromAscii(Natives::GetScriptSource(index));
Heap::natives_source_cache()->set(index, *source_code);
}
}
Handle<Object> cached_source(Heap::natives_source_cache()->get(index));
return Handle<String>::cast(cached_source);
Expand All @@ -125,6 +146,16 @@ void Bootstrapper::Initialize(bool create_heap_objects) {


void Bootstrapper::TearDown() {
if (delete_these_non_arrays_on_tear_down != NULL) {
int len = delete_these_non_arrays_on_tear_down->length();
ASSERT(len < 20); // Don't use this mechanism for unbounded allocations.
for (int i = 0; i < len; i++) {
delete delete_these_non_arrays_on_tear_down->at(i);
}
delete delete_these_non_arrays_on_tear_down;
delete_these_non_arrays_on_tear_down = NULL;
}

natives_cache.Initialize(false); // Yes, symmetrical
extensions_cache.Initialize(false);
}
Expand Down
19 changes: 19 additions & 0 deletions src/bootstrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,25 @@ class Bootstrapper : public AllStatic {
static void FreeThreadResources();
};


class NativesExternalStringResource
: public v8::String::ExternalAsciiStringResource {
public:
explicit NativesExternalStringResource(const char* source)
: data_(source), length_(strlen(source)) { }

const char* data() const {
return data_;
}

size_t length() const {
return length_;
}
private:
const char* data_;
size_t length_;
};

}} // namespace v8::internal

#endif // V8_BOOTSTRAPPER_H_
8 changes: 0 additions & 8 deletions src/objects-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,6 @@ bool Object::IsConsString() {
}


#ifdef DEBUG
// These are for cast checks. If you need one of these in release
// mode you should consider using a StringShape before moving it out
// of the ifdef

bool Object::IsSeqString() {
if (!IsString()) return false;
return StringShape(String::cast(this)).IsSequential();
Expand Down Expand Up @@ -214,9 +209,6 @@ bool Object::IsSlicedString() {
}


#endif // DEBUG


StringShape::StringShape(String* str)
: type_(str->map()->instance_type()) {
set_valid();
Expand Down
40 changes: 33 additions & 7 deletions src/objects.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,15 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
case kSlicedStringTag:
reinterpret_cast<SlicedString*>(this)->SlicedStringIterateBody(v);
break;
case kExternalStringTag:
if ((type & kStringEncodingMask) == kAsciiStringTag) {
reinterpret_cast<ExternalAsciiString*>(this)->
ExternalAsciiStringIterateBody(v);
} else {
reinterpret_cast<ExternalTwoByteString*>(this)->
ExternalTwoByteStringIterateBody(v);
}
break;
}
return;
}
Expand Down Expand Up @@ -4146,13 +4155,13 @@ void String::ReadBlockIntoBuffer(String* input,
return;
case kExternalStringTag:
if (input->IsAsciiRepresentation()) {
ExternalAsciiString::cast(input)->
ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars);
} else {
ExternalTwoByteString::cast(input)->
ExternalTwoByteStringReadBlockIntoBuffer(rbb,
offset_ptr,
max_chars);
ExternalAsciiString::cast(input)->
ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars);
} else {
ExternalTwoByteString::cast(input)->
ExternalTwoByteStringReadBlockIntoBuffer(rbb,
offset_ptr,
max_chars);
}
return;
default:
Expand Down Expand Up @@ -4398,6 +4407,23 @@ void SlicedString::SlicedStringIterateBody(ObjectVisitor* v) {
IteratePointer(v, kBufferOffset);
}

#define FIELD_ADDR(p, offset) \
(reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)

void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
typedef v8::String::ExternalAsciiStringResource Resource;
v->VisitExternalAsciiString(
reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
}


void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
typedef v8::String::ExternalStringResource Resource;
v->VisitExternalTwoByteString(
reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
}

#undef FIELD_ADDR

uint16_t SlicedString::SlicedStringGet(int index) {
ASSERT(index >= 0 && index < this->length());
Expand Down
14 changes: 12 additions & 2 deletions src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,6 @@ class Object BASE_EMBEDDED {
inline bool IsHeapNumber();
inline bool IsString();
inline bool IsSymbol();
#ifdef DEBUG
// See objects-inl.h for more details
inline bool IsSeqString();
inline bool IsSlicedString();
Expand All @@ -799,7 +798,6 @@ class Object BASE_EMBEDDED {
inline bool IsExternalAsciiString();
inline bool IsSeqTwoByteString();
inline bool IsSeqAsciiString();
#endif // DEBUG
inline bool IsConsString();

inline bool IsNumber();
Expand Down Expand Up @@ -4438,6 +4436,9 @@ class ExternalAsciiString: public ExternalString {
// Casting.
static inline ExternalAsciiString* cast(Object* obj);

// Garbage collection support.
void ExternalAsciiStringIterateBody(ObjectVisitor* v);

// Support for StringInputBuffer.
const unibrow::byte* ExternalAsciiStringReadBlock(unsigned* remaining,
unsigned* offset,
Expand Down Expand Up @@ -4473,6 +4474,9 @@ class ExternalTwoByteString: public ExternalString {
// Casting.
static inline ExternalTwoByteString* cast(Object* obj);

// Garbage collection support.
void ExternalTwoByteStringIterateBody(ObjectVisitor* v);

// Support for StringInputBuffer.
void ExternalTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
unsigned* offset_ptr,
Expand Down Expand Up @@ -5104,6 +5108,12 @@ class ObjectVisitor BASE_EMBEDDED {
// Visits a runtime entry in the instruction stream.
virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}

// Visits the resource of an ASCII or two-byte string.
virtual void VisitExternalAsciiString(
v8::String::ExternalAsciiStringResource** resource) {}
virtual void VisitExternalTwoByteString(
v8::String::ExternalStringResource** resource) {}

// Visits a debug call target in the instruction stream.
virtual void VisitDebugTarget(RelocInfo* rinfo);

Expand Down
38 changes: 37 additions & 1 deletion src/serialize.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "stub-cache.h"
#include "v8threads.h"
#include "top.h"
#include "bootstrapper.h"

namespace v8 {
namespace internal {
Expand Down Expand Up @@ -2062,6 +2063,14 @@ void Deserializer2::ReadChunk(Object** current,
pages_[space].Add(last_object_address_);
break;
}
case NATIVES_STRING_RESOURCE: {
int index = source_->Get();
Vector<const char> source_vector = Natives::GetScriptSource(index);
NativesExternalStringResource* resource =
new NativesExternalStringResource(source_vector.start());
*current++ = reinterpret_cast<Object*>(resource);
break;
}
default:
UNREACHABLE();
}
Expand Down Expand Up @@ -2253,7 +2262,7 @@ void Serializer2::ObjectSerializer::VisitPointers(Object** start,
Object** current = start;
while (current < end) {
while (current < end && (*current)->IsSmi()) current++;
OutputRawData(reinterpret_cast<Address>(current));
if (current < end) OutputRawData(reinterpret_cast<Address>(current));

while (current < end && !(*current)->IsSmi()) {
serializer_->SerializeObject(*current, TAGGED_REPRESENTATION);
Expand Down Expand Up @@ -2300,6 +2309,33 @@ void Serializer2::ObjectSerializer::VisitCodeTarget(RelocInfo* rinfo) {
}


void Serializer2::ObjectSerializer::VisitExternalAsciiString(
v8::String::ExternalAsciiStringResource** resource_pointer) {
Address references_start = reinterpret_cast<Address>(resource_pointer);
OutputRawData(references_start);
for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
// Use raw_unchecked when maps are munged.
Object* source = Heap::raw_unchecked_natives_source_cache()->get(i);
if (!source->IsUndefined()) {
// Don't use cast when maps are munged.
ExternalAsciiString* string =
reinterpret_cast<ExternalAsciiString*>(source);
typedef v8::String::ExternalAsciiStringResource Resource;
Resource* resource = string->resource();
if (resource == *resource_pointer) {
sink_->Put(NATIVES_STRING_RESOURCE, "NativesStringResource");
sink_->PutSection(i, "NativesStringResourceEnd");
bytes_processed_so_far_ += sizeof(resource);
return;
}
}
}
// One of the strings in the natives cache should match the resource. We
// can't serialize any other kinds of external strings.
UNREACHABLE();
}


void Serializer2::ObjectSerializer::OutputRawData(Address up_to) {
Address object_start = object_->address();
int up_to_offset = up_to - object_start;
Expand Down
11 changes: 10 additions & 1 deletion src/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,8 @@ class SerDes: public GenericDeserializer {
EXTERNAL_BRANCH_TARGET_SERIALIZATION = 35,
SYNCHRONIZE = 36,
START_NEW_PAGE_SERIALIZATION = 37,
// Free: 38-47.
NATIVES_STRING_RESOURCE = 38,
// Free: 39-47.
BACKREF_SERIALIZATION = 48,
// One per space, must be kSpaceMask aligned.
// Free: 57-63.
Expand Down Expand Up @@ -567,6 +568,14 @@ class Serializer2 : public SerDes {
void VisitExternalReferences(Address* start, Address* end);
void VisitCodeTarget(RelocInfo* target);
void VisitRuntimeEntry(RelocInfo* reloc);
// Used for seralizing the external strings that hold the natives source.
void VisitExternalAsciiString(
v8::String::ExternalAsciiStringResource** resource);
// We can't serialize a heap with external two byte strings.
void VisitExternalTwoByteString(
v8::String::ExternalStringResource** resource) {
UNREACHABLE();
}

private:
void OutputRawData(Address up_to);
Expand Down
6 changes: 3 additions & 3 deletions test/cctest/cctest.status
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ test-api/ApplyInterruption: PASS || TIMEOUT

# This is about to go away anyway since new snapshot code is on the way.
test-serialize/Deserialize: FAIL
test-serialize/DeserializeAndRunScript: FAIL
test-serialize/DeserializeNatives: FAIL
test-serialize/DeserializeExtensions: FAIL
test-serialize/DeserializeAndRunScript: FAIL || CRASH
test-serialize/DeserializeNatives: FAIL || CRASH
test-serialize/DeserializeExtensions: FAIL || CRASH

# These tests always fail. They are here to test test.py. If
# they don't fail then test.py has failed.
Expand Down
2 changes: 1 addition & 1 deletion tools/js2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ def JS2C(source, target, env):
else:
ids.append((id, len(lines)))
source_lines.append(SOURCE_DECLARATION % { 'id': id, 'data': data })
source_lines_empty.append(SOURCE_DECLARATION % { 'id': id, 'data': 0 })
source_lines_empty.append(SOURCE_DECLARATION % { 'id': id, 'data': data })

# Build delay support functions
get_index_cases = [ ]
Expand Down

0 comments on commit 6a3921f

Please sign in to comment.