Skip to content

Commit 6a3921f

Browse files
Keep natives source code in external strings instead of putting
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
1 parent 321bed2 commit 6a3921f

10 files changed

+149
-27
lines changed

src/SConscript

-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,6 @@ def ConfigureObjectFiles():
264264
else:
265265
snapshot_cc = Command('snapshot.cc', [], [])
266266
snapshot_obj = context.ConfigureObject(env, snapshot_cc, CPPPATH=['.'])
267-
libraries_obj = context.ConfigureObject(env, libraries_empty_src, CPPPATH=['.'])
268267
else:
269268
snapshot_obj = empty_snapshot_obj
270269
library_objs = [non_snapshot_files, libraries_obj, snapshot_obj]

src/bootstrapper.cc

+34-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "global-handles.h"
3737
#include "macro-assembler.h"
3838
#include "natives.h"
39+
#include "snapshot.h"
3940

4041
namespace v8 {
4142
namespace internal {
@@ -92,14 +93,34 @@ class SourceCodeCache BASE_EMBEDDED {
9293

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

9699

97100
Handle<String> Bootstrapper::NativesSourceLookup(int index) {
98101
ASSERT(0 <= index && index < Natives::GetBuiltinsCount());
99102
if (Heap::natives_source_cache()->get(index)->IsUndefined()) {
100-
Handle<String> source_code =
101-
Factory::NewStringFromAscii(Natives::GetScriptSource(index));
102-
Heap::natives_source_cache()->set(index, *source_code);
103+
if (!Snapshot::IsEnabled || FLAG_new_snapshot) {
104+
if (delete_these_non_arrays_on_tear_down == NULL) {
105+
delete_these_non_arrays_on_tear_down = new List<char*>(2);
106+
}
107+
// We can use external strings for the natives.
108+
NativesExternalStringResource* resource =
109+
new NativesExternalStringResource(
110+
Natives::GetScriptSource(index).start());
111+
// The resources are small objects and we only make a fixed number of
112+
// them, but lets clean them up on exit for neatness.
113+
delete_these_non_arrays_on_tear_down->
114+
Add(reinterpret_cast<char*>(resource));
115+
Handle<String> source_code =
116+
Factory::NewExternalStringFromAscii(resource);
117+
Heap::natives_source_cache()->set(index, *source_code);
118+
} else {
119+
// Old snapshot code can't cope with external strings at all.
120+
Handle<String> source_code =
121+
Factory::NewStringFromAscii(Natives::GetScriptSource(index));
122+
Heap::natives_source_cache()->set(index, *source_code);
123+
}
103124
}
104125
Handle<Object> cached_source(Heap::natives_source_cache()->get(index));
105126
return Handle<String>::cast(cached_source);
@@ -125,6 +146,16 @@ void Bootstrapper::Initialize(bool create_heap_objects) {
125146

126147

127148
void Bootstrapper::TearDown() {
149+
if (delete_these_non_arrays_on_tear_down != NULL) {
150+
int len = delete_these_non_arrays_on_tear_down->length();
151+
ASSERT(len < 20); // Don't use this mechanism for unbounded allocations.
152+
for (int i = 0; i < len; i++) {
153+
delete delete_these_non_arrays_on_tear_down->at(i);
154+
}
155+
delete delete_these_non_arrays_on_tear_down;
156+
delete_these_non_arrays_on_tear_down = NULL;
157+
}
158+
128159
natives_cache.Initialize(false); // Yes, symmetrical
129160
extensions_cache.Initialize(false);
130161
}

src/bootstrapper.h

+19
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,25 @@ class Bootstrapper : public AllStatic {
7676
static void FreeThreadResources();
7777
};
7878

79+
80+
class NativesExternalStringResource
81+
: public v8::String::ExternalAsciiStringResource {
82+
public:
83+
explicit NativesExternalStringResource(const char* source)
84+
: data_(source), length_(strlen(source)) { }
85+
86+
const char* data() const {
87+
return data_;
88+
}
89+
90+
size_t length() const {
91+
return length_;
92+
}
93+
private:
94+
const char* data_;
95+
size_t length_;
96+
};
97+
7998
}} // namespace v8::internal
8099

81100
#endif // V8_BOOTSTRAPPER_H_

src/objects-inl.h

-8
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,6 @@ bool Object::IsConsString() {
163163
}
164164

165165

166-
#ifdef DEBUG
167-
// These are for cast checks. If you need one of these in release
168-
// mode you should consider using a StringShape before moving it out
169-
// of the ifdef
170-
171166
bool Object::IsSeqString() {
172167
if (!IsString()) return false;
173168
return StringShape(String::cast(this)).IsSequential();
@@ -214,9 +209,6 @@ bool Object::IsSlicedString() {
214209
}
215210

216211

217-
#endif // DEBUG
218-
219-
220212
StringShape::StringShape(String* str)
221213
: type_(str->map()->instance_type()) {
222214
set_valid();

src/objects.cc

+33-7
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,15 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
11381138
case kSlicedStringTag:
11391139
reinterpret_cast<SlicedString*>(this)->SlicedStringIterateBody(v);
11401140
break;
1141+
case kExternalStringTag:
1142+
if ((type & kStringEncodingMask) == kAsciiStringTag) {
1143+
reinterpret_cast<ExternalAsciiString*>(this)->
1144+
ExternalAsciiStringIterateBody(v);
1145+
} else {
1146+
reinterpret_cast<ExternalTwoByteString*>(this)->
1147+
ExternalTwoByteStringIterateBody(v);
1148+
}
1149+
break;
11411150
}
11421151
return;
11431152
}
@@ -4146,13 +4155,13 @@ void String::ReadBlockIntoBuffer(String* input,
41464155
return;
41474156
case kExternalStringTag:
41484157
if (input->IsAsciiRepresentation()) {
4149-
ExternalAsciiString::cast(input)->
4150-
ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars);
4151-
} else {
4152-
ExternalTwoByteString::cast(input)->
4153-
ExternalTwoByteStringReadBlockIntoBuffer(rbb,
4154-
offset_ptr,
4155-
max_chars);
4158+
ExternalAsciiString::cast(input)->
4159+
ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars);
4160+
} else {
4161+
ExternalTwoByteString::cast(input)->
4162+
ExternalTwoByteStringReadBlockIntoBuffer(rbb,
4163+
offset_ptr,
4164+
max_chars);
41564165
}
41574166
return;
41584167
default:
@@ -4398,6 +4407,23 @@ void SlicedString::SlicedStringIterateBody(ObjectVisitor* v) {
43984407
IteratePointer(v, kBufferOffset);
43994408
}
44004409

4410+
#define FIELD_ADDR(p, offset) \
4411+
(reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
4412+
4413+
void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4414+
typedef v8::String::ExternalAsciiStringResource Resource;
4415+
v->VisitExternalAsciiString(
4416+
reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4417+
}
4418+
4419+
4420+
void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4421+
typedef v8::String::ExternalStringResource Resource;
4422+
v->VisitExternalTwoByteString(
4423+
reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4424+
}
4425+
4426+
#undef FIELD_ADDR
44014427

44024428
uint16_t SlicedString::SlicedStringGet(int index) {
44034429
ASSERT(index >= 0 && index < this->length());

src/objects.h

+12-2
Original file line numberDiff line numberDiff line change
@@ -790,7 +790,6 @@ class Object BASE_EMBEDDED {
790790
inline bool IsHeapNumber();
791791
inline bool IsString();
792792
inline bool IsSymbol();
793-
#ifdef DEBUG
794793
// See objects-inl.h for more details
795794
inline bool IsSeqString();
796795
inline bool IsSlicedString();
@@ -799,7 +798,6 @@ class Object BASE_EMBEDDED {
799798
inline bool IsExternalAsciiString();
800799
inline bool IsSeqTwoByteString();
801800
inline bool IsSeqAsciiString();
802-
#endif // DEBUG
803801
inline bool IsConsString();
804802

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

4439+
// Garbage collection support.
4440+
void ExternalAsciiStringIterateBody(ObjectVisitor* v);
4441+
44414442
// Support for StringInputBuffer.
44424443
const unibrow::byte* ExternalAsciiStringReadBlock(unsigned* remaining,
44434444
unsigned* offset,
@@ -4473,6 +4474,9 @@ class ExternalTwoByteString: public ExternalString {
44734474
// Casting.
44744475
static inline ExternalTwoByteString* cast(Object* obj);
44754476

4477+
// Garbage collection support.
4478+
void ExternalTwoByteStringIterateBody(ObjectVisitor* v);
4479+
44764480
// Support for StringInputBuffer.
44774481
void ExternalTwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* buffer,
44784482
unsigned* offset_ptr,
@@ -5104,6 +5108,12 @@ class ObjectVisitor BASE_EMBEDDED {
51045108
// Visits a runtime entry in the instruction stream.
51055109
virtual void VisitRuntimeEntry(RelocInfo* rinfo) {}
51065110

5111+
// Visits the resource of an ASCII or two-byte string.
5112+
virtual void VisitExternalAsciiString(
5113+
v8::String::ExternalAsciiStringResource** resource) {}
5114+
virtual void VisitExternalTwoByteString(
5115+
v8::String::ExternalStringResource** resource) {}
5116+
51075117
// Visits a debug call target in the instruction stream.
51085118
virtual void VisitDebugTarget(RelocInfo* rinfo);
51095119

src/serialize.cc

+37-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "stub-cache.h"
4040
#include "v8threads.h"
4141
#include "top.h"
42+
#include "bootstrapper.h"
4243

4344
namespace v8 {
4445
namespace internal {
@@ -2062,6 +2063,14 @@ void Deserializer2::ReadChunk(Object** current,
20622063
pages_[space].Add(last_object_address_);
20632064
break;
20642065
}
2066+
case NATIVES_STRING_RESOURCE: {
2067+
int index = source_->Get();
2068+
Vector<const char> source_vector = Natives::GetScriptSource(index);
2069+
NativesExternalStringResource* resource =
2070+
new NativesExternalStringResource(source_vector.start());
2071+
*current++ = reinterpret_cast<Object*>(resource);
2072+
break;
2073+
}
20652074
default:
20662075
UNREACHABLE();
20672076
}
@@ -2253,7 +2262,7 @@ void Serializer2::ObjectSerializer::VisitPointers(Object** start,
22532262
Object** current = start;
22542263
while (current < end) {
22552264
while (current < end && (*current)->IsSmi()) current++;
2256-
OutputRawData(reinterpret_cast<Address>(current));
2265+
if (current < end) OutputRawData(reinterpret_cast<Address>(current));
22572266

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

23022311

2312+
void Serializer2::ObjectSerializer::VisitExternalAsciiString(
2313+
v8::String::ExternalAsciiStringResource** resource_pointer) {
2314+
Address references_start = reinterpret_cast<Address>(resource_pointer);
2315+
OutputRawData(references_start);
2316+
for (int i = 0; i < Natives::GetBuiltinsCount(); i++) {
2317+
// Use raw_unchecked when maps are munged.
2318+
Object* source = Heap::raw_unchecked_natives_source_cache()->get(i);
2319+
if (!source->IsUndefined()) {
2320+
// Don't use cast when maps are munged.
2321+
ExternalAsciiString* string =
2322+
reinterpret_cast<ExternalAsciiString*>(source);
2323+
typedef v8::String::ExternalAsciiStringResource Resource;
2324+
Resource* resource = string->resource();
2325+
if (resource == *resource_pointer) {
2326+
sink_->Put(NATIVES_STRING_RESOURCE, "NativesStringResource");
2327+
sink_->PutSection(i, "NativesStringResourceEnd");
2328+
bytes_processed_so_far_ += sizeof(resource);
2329+
return;
2330+
}
2331+
}
2332+
}
2333+
// One of the strings in the natives cache should match the resource. We
2334+
// can't serialize any other kinds of external strings.
2335+
UNREACHABLE();
2336+
}
2337+
2338+
23032339
void Serializer2::ObjectSerializer::OutputRawData(Address up_to) {
23042340
Address object_start = object_->address();
23052341
int up_to_offset = up_to - object_start;

src/serialize.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,8 @@ class SerDes: public GenericDeserializer {
441441
EXTERNAL_BRANCH_TARGET_SERIALIZATION = 35,
442442
SYNCHRONIZE = 36,
443443
START_NEW_PAGE_SERIALIZATION = 37,
444-
// Free: 38-47.
444+
NATIVES_STRING_RESOURCE = 38,
445+
// Free: 39-47.
445446
BACKREF_SERIALIZATION = 48,
446447
// One per space, must be kSpaceMask aligned.
447448
// Free: 57-63.
@@ -567,6 +568,14 @@ class Serializer2 : public SerDes {
567568
void VisitExternalReferences(Address* start, Address* end);
568569
void VisitCodeTarget(RelocInfo* target);
569570
void VisitRuntimeEntry(RelocInfo* reloc);
571+
// Used for seralizing the external strings that hold the natives source.
572+
void VisitExternalAsciiString(
573+
v8::String::ExternalAsciiStringResource** resource);
574+
// We can't serialize a heap with external two byte strings.
575+
void VisitExternalTwoByteString(
576+
v8::String::ExternalStringResource** resource) {
577+
UNREACHABLE();
578+
}
570579

571580
private:
572581
void OutputRawData(Address up_to);

test/cctest/cctest.status

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ test-api/ApplyInterruption: PASS || TIMEOUT
3535

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

4242
# These tests always fail. They are here to test test.py. If
4343
# they don't fail then test.py has failed.

tools/js2c.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def JS2C(source, target, env):
301301
else:
302302
ids.append((id, len(lines)))
303303
source_lines.append(SOURCE_DECLARATION % { 'id': id, 'data': data })
304-
source_lines_empty.append(SOURCE_DECLARATION % { 'id': id, 'data': 0 })
304+
source_lines_empty.append(SOURCE_DECLARATION % { 'id': id, 'data': data })
305305

306306
# Build delay support functions
307307
get_index_cases = [ ]

0 commit comments

Comments
 (0)