Revert "Keep the line starts delta encoded in the VM heap as well."

This reverts commit cd4e5ee866.

Reason for revert: This broke the 32bit Linux SDK build. 

Original change's description:
> Keep the line starts delta encoded in the VM heap as well.
> 
> The line starts in the kernel binary are delta encoded. By decoding and
> storing them as int32 values, we are unneccesarily bloating the VM heap.
> This change keeps the line starts delta encoded in the VM heap as well.
> This brings down the core snapshot size by 275KB (but will of course
> affect the debug performance.)
> 
> Bug:
> Change-Id: I77769efe7339484096d04c37180367adf96e51f4
> Reviewed-on: https://dart-review.googlesource.com/22304
> Commit-Queue: Siva Chandra <sivachandra@google.com>
> Reviewed-by: Siva Annamalai <asiva@google.com>

TBR=sivachandra@google.com,asiva@google.com

Change-Id: I6e78bd510de7033d8583c089c00b5b261fdf69c1
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/24800
Reviewed-by: Alexander Thomas <athom@google.com>
Commit-Queue: Alexander Thomas <athom@google.com>
This commit is contained in:
Alexander Thomas 2017-11-30 09:32:29 +00:00 committed by commit-bot@chromium.org
parent 9ddb267c41
commit adf04d0ac6
4 changed files with 55 additions and 256 deletions

View file

@ -9174,51 +9174,19 @@ String& StreamingFlowGraphBuilder::GetSourceFor(intptr_t index) {
}
RawTypedData* StreamingFlowGraphBuilder::GetLineStartsFor(intptr_t index) {
// Line starts are delta encoded. So get the max delta first so that we
// can store them as tighly as possible.
AlternativeReadingScope alt(reader_);
SetOffset(GetOffsetForSourceInfo(index));
SkipBytes(ReadUInt()); // skip uri.
SkipBytes(ReadUInt()); // skip source.
const intptr_t line_start_count = ReadUInt(); // read number of line start
// entries.
MallocGrowableArray<int32_t> line_starts_array;
SkipBytes(ReadUInt()); // skip uri.
SkipBytes(ReadUInt()); // skip source.
intptr_t size = ReadUInt(); // read line starts length.
intptr_t max_delta = 0;
for (intptr_t i = 0; i < line_start_count; ++i) {
int32_t delta = ReadUInt();
line_starts_array.Add(delta);
if (delta > max_delta) {
max_delta = delta;
}
}
intptr_t cid;
if (max_delta <= INT8_MAX) {
cid = kTypedDataInt8ArrayCid;
} else if (max_delta <= INT16_MAX) {
cid = kTypedDataInt16ArrayCid;
} else {
cid = kTypedDataInt32ArrayCid;
}
TypedData& line_starts_data =
TypedData::Handle(Z, TypedData::New(cid, line_start_count, Heap::kOld));
for (intptr_t j = 0; j < line_start_count; ++j) {
int32_t line_start = line_starts_array[j];
switch (cid) {
case kTypedDataInt8ArrayCid:
line_starts_data.SetInt8(j, static_cast<int8_t>(line_start));
break;
case kTypedDataInt16ArrayCid:
line_starts_data.SetInt16(j << 1, static_cast<int16_t>(line_start));
break;
case kTypedDataInt32ArrayCid:
line_starts_data.SetInt32(j << 2, line_start);
break;
default:
UNREACHABLE();
}
TypedData& line_starts_data = TypedData::Handle(
Z, TypedData::New(kTypedDataInt32ArrayCid, size, Heap::kOld));
intptr_t previous_line_start = 0;
for (intptr_t j = 0; j < size; ++j) {
intptr_t line_start = ReadUInt() + previous_line_start;
line_starts_data.SetInt32(j * 4, line_start);
previous_line_start = line_start;
}
return line_starts_data.raw();
}

View file

@ -28,112 +28,6 @@ bool FieldHasFunctionLiteralInitializer(const Field& field,
return field_helper.FieldHasFunctionLiteralInitializer(start, end);
}
KernelLineStartsReader::KernelLineStartsReader(
const dart::TypedData& line_starts_data,
dart::Zone* zone)
: line_starts_data_(line_starts_data) {
TypedDataElementType type = line_starts_data_.ElementType();
if (type == kInt8ArrayElement) {
helper_ = new KernelInt8LineStartsHelper();
} else if (type == kInt16ArrayElement) {
helper_ = new KernelInt16LineStartsHelper();
} else if (type == kInt32ArrayElement) {
helper_ = new KernelInt32LineStartsHelper();
} else {
UNREACHABLE();
}
}
intptr_t KernelLineStartsReader::LineNumberForPosition(
intptr_t position) const {
intptr_t line_count = line_starts_data_.Length();
intptr_t current_start = 0;
for (intptr_t i = 0; i < line_count; ++i) {
current_start += helper_->At(line_starts_data_, i);
if (current_start > position) {
// If current_start is greater than the desired position, it means that
// it is for the line after |position|. However, since line numbers
// start at 1, we just return |i|.
return i;
}
if (current_start == position) {
return i + 1;
}
}
return line_count;
}
void KernelLineStartsReader::LocationForPosition(intptr_t position,
intptr_t* line,
intptr_t* col) const {
intptr_t line_count = line_starts_data_.Length();
intptr_t current_start = 0;
intptr_t previous_start = 0;
for (intptr_t i = 0; i < line_count; ++i) {
current_start += helper_->At(line_starts_data_, i);
if (current_start > position) {
*line = i;
if (col != NULL) {
*col = position - previous_start + 1;
}
return;
}
if (current_start == position) {
*line = i + 1;
if (col != NULL) {
*col = 1;
}
return;
}
previous_start = current_start;
}
// If the start of any of the lines did not cross |position|,
// then it means the position falls on the last line.
*line = line_count;
if (col != NULL) {
*col = position - current_start + 1;
}
}
void KernelLineStartsReader::TokenRangeAtLine(
intptr_t source_length,
intptr_t line_number,
TokenPosition* first_token_index,
TokenPosition* last_token_index) const {
ASSERT(line_number <= line_starts_data_.Length());
intptr_t cumulative = 0;
for (intptr_t i = 0; i < line_number; ++i) {
cumulative += helper_->At(line_starts_data_, i);
}
*first_token_index = dart::TokenPosition(cumulative);
if (line_number == line_starts_data_.Length()) {
*last_token_index = dart::TokenPosition(source_length);
} else {
*last_token_index = dart::TokenPosition(
cumulative + helper_->At(line_starts_data_, line_number) - 1);
}
}
int32_t KernelLineStartsReader::KernelInt8LineStartsHelper::At(
const dart::TypedData& data,
intptr_t index) const {
return data.GetInt8(index);
}
int32_t KernelLineStartsReader::KernelInt16LineStartsHelper::At(
const dart::TypedData& data,
intptr_t index) const {
return data.GetInt16(index << 1);
}
int32_t KernelLineStartsReader::KernelInt32LineStartsHelper::At(
const dart::TypedData& data,
intptr_t index) const {
return data.GetInt32(index << 2);
}
} // namespace kernel
} // namespace dart

View file

@ -114,72 +114,6 @@ class Program {
DISALLOW_COPY_AND_ASSIGN(Program);
};
class KernelLineStartsReader {
public:
KernelLineStartsReader(const dart::TypedData& line_starts_data,
dart::Zone* zone);
~KernelLineStartsReader() { delete helper_; }
int32_t DeltaAt(intptr_t index) const {
return helper_->At(line_starts_data_, index);
}
intptr_t LineNumberForPosition(intptr_t position) const;
void LocationForPosition(intptr_t position,
intptr_t* line,
intptr_t* col) const;
void TokenRangeAtLine(intptr_t source_length,
intptr_t line_number,
dart::TokenPosition* first_token_index,
dart::TokenPosition* last_token_index) const;
private:
class KernelLineStartsHelper {
public:
KernelLineStartsHelper() {}
virtual ~KernelLineStartsHelper() {}
virtual int32_t At(const dart::TypedData& data, intptr_t index) const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(KernelLineStartsHelper);
};
class KernelInt8LineStartsHelper : public KernelLineStartsHelper {
public:
KernelInt8LineStartsHelper() {}
virtual int32_t At(const dart::TypedData& data, intptr_t index) const;
private:
DISALLOW_COPY_AND_ASSIGN(KernelInt8LineStartsHelper);
};
class KernelInt16LineStartsHelper : public KernelLineStartsHelper {
public:
KernelInt16LineStartsHelper() {}
virtual int32_t At(const dart::TypedData& data, intptr_t index) const;
private:
DISALLOW_COPY_AND_ASSIGN(KernelInt16LineStartsHelper);
};
class KernelInt32LineStartsHelper : public KernelLineStartsHelper {
public:
KernelInt32LineStartsHelper() {}
virtual int32_t At(const dart::TypedData& data, intptr_t index) const;
private:
DISALLOW_COPY_AND_ASSIGN(KernelInt32LineStartsHelper);
};
const dart::TypedData& line_starts_data_;
KernelLineStartsHelper* helper_;
DISALLOW_COPY_AND_ASSIGN(KernelLineStartsReader);
};
ParsedFunction* ParseStaticFieldInitializer(Zone* zone, const Field& field);
bool FieldHasFunctionLiteralInitializer(const Field& field,

View file

@ -31,7 +31,6 @@
#include "vm/hash_table.h"
#include "vm/heap.h"
#include "vm/isolate_reload.h"
#include "vm/kernel.h"
#include "vm/native_symbol.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@ -9225,21 +9224,18 @@ RawGrowableObjectArray* Script::GenerateLineNumberArray() const {
info.Add(line_separator); // New line.
return info.raw();
}
#if !defined(DART_PRECOMPILED_RUNTIME)
intptr_t line_count = line_starts_data.Length();
ASSERT(line_count > 0);
const Array& debug_positions_array = Array::Handle(debug_positions());
intptr_t token_count = debug_positions_array.Length();
int token_index = 0;
kernel::KernelLineStartsReader line_starts_reader(line_starts_data, zone);
intptr_t previous_start = 0;
for (int line_index = 0; line_index < line_count; ++line_index) {
intptr_t start = previous_start + line_starts_reader.DeltaAt(line_index);
intptr_t start = line_starts_data.GetInt32(line_index * 4);
// Output the rest of the tokens if we have no next line.
intptr_t end = TokenPosition::kMaxSourcePos;
if (line_index + 1 < line_count) {
end = start + line_starts_reader.DeltaAt(line_index + 1);
end = line_starts_data.GetInt32((line_index + 1) * 4);
}
bool first = true;
while (token_index < token_count) {
@ -9260,9 +9256,7 @@ RawGrowableObjectArray* Script::GenerateLineNumberArray() const {
info.Add(value);
++token_index;
}
previous_start = start;
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
return info.raw();
}
@ -9496,31 +9490,22 @@ intptr_t Script::GetTokenLineUsingLineStarts(
set_line_starts(line_starts_data);
}
if (kind() == RawScript::kKernelTag) {
#if !defined(DART_PRECOMPILED_RUNTIME)
kernel::KernelLineStartsReader line_starts_reader(line_starts_data, zone);
return line_starts_reader.LineNumberForPosition(target_token_pos.value());
#else
return 0;
#endif // !defined(DART_PRECOMPILED_RUNTIME)
} else {
ASSERT(line_starts_data.Length() > 0);
intptr_t offset = target_token_pos.Pos();
intptr_t min = 0;
intptr_t max = line_starts_data.Length() - 1;
ASSERT(line_starts_data.Length() > 0);
intptr_t offset = target_token_pos.Pos();
intptr_t min = 0;
intptr_t max = line_starts_data.Length() - 1;
// Binary search to find the line containing this offset.
while (min < max) {
int midpoint = (max - min + 1) / 2 + min;
int32_t token_pos = line_starts_data.GetInt32(midpoint * 4);
if (token_pos > offset) {
max = midpoint - 1;
} else {
min = midpoint;
}
// Binary search to find the line containing this offset.
while (min < max) {
int midpoint = (max - min + 1) / 2 + min;
int32_t token_pos = line_starts_data.GetInt32(midpoint * 4);
if (token_pos > offset) {
max = midpoint - 1;
} else {
min = midpoint;
}
return min + 1; // Line numbers start at 1.
}
return min + 1; // Line numbers start at 1.
}
void Script::GetTokenLocation(TokenPosition token_pos,
@ -9543,15 +9528,31 @@ void Script::GetTokenLocation(TokenPosition token_pos,
}
return;
}
#if !defined(DART_PRECOMPILED_RUNTIME)
ASSERT(line_starts_data.Length() > 0);
kernel::KernelLineStartsReader line_starts_reader(line_starts_data, zone);
line_starts_reader.LocationForPosition(token_pos.value(), line, column);
intptr_t offset = token_pos.value();
intptr_t min = 0;
intptr_t max = line_starts_data.Length() - 1;
// Binary search to find the line containing this offset.
while (min < max) {
intptr_t midpoint = (max - min + 1) / 2 + min;
int32_t value = line_starts_data.GetInt32(midpoint * 4);
if (value > offset) {
max = midpoint - 1;
} else {
min = midpoint;
}
}
*line = min + 1; // Line numbers start at 1.
int32_t min_value = line_starts_data.GetInt32(min * 4);
if (column != NULL) {
*column = offset - min_value + 1;
}
if (token_len != NULL) {
// We don't explicitly save this data: Load the source
// and find it from there.
const String& source = String::Handle(zone, Source());
intptr_t offset = token_pos.value();
*token_len = 1;
if (offset < source.Length() &&
Scanner::IsIdentStartChar(source.CharAt(offset))) {
@ -9562,7 +9563,6 @@ void Script::GetTokenLocation(TokenPosition token_pos,
}
}
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
return;
}
@ -9626,13 +9626,16 @@ void Script::TokenRangeAtLine(intptr_t line_number,
*last_token_index = TokenPosition::kNoSource;
return;
}
#if !defined(DART_PRECOMPILED_RUNTIME)
kernel::KernelLineStartsReader line_starts_reader(
line_starts_data, Thread::Current()->zone());
line_starts_reader.TokenRangeAtLine(String::Handle(Source()).Length(),
line_number, first_token_index,
last_token_index);
#endif // !defined(DART_PRECOMPILED_RUNTIME)
ASSERT(line_starts_data.Length() >= line_number);
int32_t value = line_starts_data.GetInt32((line_number - 1) * 4);
*first_token_index = TokenPosition(value);
if (line_starts_data.Length() > line_number) {
value = line_starts_data.GetInt32(line_number * 4);
*last_token_index = TokenPosition(value - 1);
} else {
// Length of source is last possible token in this script.
*last_token_index = TokenPosition(String::Handle(Source()).Length());
}
return;
}