Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: courgette/encoded_program.cc

Issue 6597038: Implementation of an STL compatible allocator for Courgette on Windows.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "courgette/encoded_program.h" 5 #include "courgette/encoded_program.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 21 matching lines...) Expand all
32 32
33 const int kStreamLimit = 9; 33 const int kStreamLimit = 9;
34 34
35 // Constructor is here rather than in the header. Although the constructor 35 // Constructor is here rather than in the header. Although the constructor
36 // appears to do nothing it is fact quite large because of the implict calls to 36 // appears to do nothing it is fact quite large because of the implict calls to
37 // field constructors. Ditto for the destructor. 37 // field constructors. Ditto for the destructor.
38 EncodedProgram::EncodedProgram() : image_base_(0) {} 38 EncodedProgram::EncodedProgram() : image_base_(0) {}
39 EncodedProgram::~EncodedProgram() {} 39 EncodedProgram::~EncodedProgram() {}
40 40
41 // Serializes a vector of integral values using Varint32 coding. 41 // Serializes a vector of integral values using Varint32 coding.
42 template<typename T> 42 template<typename T, typename A>
43 void WriteVector(const std::vector<T>& items, SinkStream* buffer) { 43 void WriteVector(const std::vector<T, A>& items, SinkStream* buffer) {
44 size_t count = items.size(); 44 size_t count = items.size();
45 buffer->WriteSizeVarint32(count); 45 buffer->WriteSizeVarint32(count);
46 for (size_t i = 0; i < count; ++i) { 46 for (size_t i = 0; i < count; ++i) {
47 COMPILE_ASSERT(sizeof(T) <= sizeof(uint32), T_must_fit_in_uint32); 47 COMPILE_ASSERT(sizeof(T) <= sizeof(uint32), // NOLINT
48 T_must_fit_in_uint32);
48 buffer->WriteSizeVarint32(items[i]); 49 buffer->WriteSizeVarint32(items[i]);
49 } 50 }
50 } 51 }
51 52
52 template<typename T> 53 template<typename T, typename A>
53 bool ReadVector(std::vector<T>* items, SourceStream* buffer) { 54 bool ReadVector(std::vector<T, A>* items, SourceStream* buffer) {
54 uint32 count; 55 uint32 count;
55 if (!buffer->ReadVarint32(&count)) 56 if (!buffer->ReadVarint32(&count))
56 return false; 57 return false;
57 58
58 items->clear(); 59 items->clear();
59 items->reserve(count); 60 items->reserve(count);
60 for (size_t i = 0; i < count; ++i) { 61 for (size_t i = 0; i < count; ++i) {
61 uint32 item; 62 uint32 item;
62 if (!buffer->ReadVarint32(&item)) 63 if (!buffer->ReadVarint32(&item))
63 return false; 64 return false;
64 items->push_back(static_cast<T>(item)); 65 items->push_back(static_cast<T>(item));
65 } 66 }
66 67
67 return true; 68 return true;
68 } 69 }
69 70
70 // Serializes a vector, using delta coding followed by Varint32 coding. 71 // Serializes a vector, using delta coding followed by Varint32 coding.
71 void WriteU32Delta(const std::vector<uint32>& set, SinkStream* buffer) { 72 template<typename A>
73 void WriteU32Delta(const std::vector<uint32, A>& set, SinkStream* buffer) {
72 size_t count = set.size(); 74 size_t count = set.size();
73 buffer->WriteSizeVarint32(count); 75 buffer->WriteSizeVarint32(count);
74 uint32 prev = 0; 76 uint32 prev = 0;
75 for (size_t i = 0; i < count; ++i) { 77 for (size_t i = 0; i < count; ++i) {
76 uint32 current = set[i]; 78 uint32 current = set[i];
77 uint32 delta = current - prev; 79 uint32 delta = current - prev;
78 buffer->WriteVarint32(delta); 80 buffer->WriteVarint32(delta);
79 prev = current; 81 prev = current;
80 } 82 }
81 } 83 }
82 84
83 static bool ReadU32Delta(std::vector<uint32>* set, SourceStream* buffer) { 85 template <typename A>
86 static bool ReadU32Delta(std::vector<uint32, A>* set, SourceStream* buffer) {
84 uint32 count; 87 uint32 count;
85 88
86 if (!buffer->ReadVarint32(&count)) 89 if (!buffer->ReadVarint32(&count))
87 return false; 90 return false;
88 91
89 set->clear(); 92 set->clear();
90 set->reserve(count); 93 set->reserve(count);
91 uint32 prev = 0; 94 uint32 prev = 0;
92 95
93 for (size_t i = 0; i < count; ++i) { 96 for (size_t i = 0; i < count; ++i) {
94 uint32 delta; 97 uint32 delta;
95 if (!buffer->ReadVarint32(&delta)) 98 if (!buffer->ReadVarint32(&delta))
96 return false; 99 return false;
97 uint32 current = prev + delta; 100 uint32 current = prev + delta;
98 set->push_back(current); 101 set->push_back(current);
99 prev = current; 102 prev = current;
100 } 103 }
101 104
102 return true; 105 return true;
103 } 106 }
104 107
105 // Write a vector as the byte representation of the contents. 108 // Write a vector as the byte representation of the contents.
106 // 109 //
107 // (This only really makes sense for a type T that has sizeof(T)==1, otherwise 110 // (This only really makes sense for a type T that has sizeof(T)==1, otherwise
108 // serilized representation is not endian-agnositic. But it is useful to keep 111 // serilized representation is not endian-agnositic. But it is useful to keep
109 // the possibility of a greater size for experiments comparing Varint32 encoding 112 // the possibility of a greater size for experiments comparing Varint32 encoding
110 // of a vector of larger integrals vs a plain form.) 113 // of a vector of larger integrals vs a plain form.)
111 // 114 //
112 template<typename T> 115 template<typename T, typename A>
113 void WriteVectorU8(const std::vector<T>& items, SinkStream* buffer) { 116 void WriteVectorU8(const std::vector<T, A>& items, SinkStream* buffer) {
114 size_t count = items.size(); 117 size_t count = items.size();
115 buffer->WriteSizeVarint32(count); 118 buffer->WriteSizeVarint32(count);
116 if (count != 0) { 119 if (count != 0) {
117 size_t byte_count = count * sizeof(T); 120 size_t byte_count = count * sizeof(T);
118 buffer->Write(static_cast<const void*>(&items[0]), byte_count); 121 buffer->Write(static_cast<const void*>(&items[0]), byte_count);
119 } 122 }
120 } 123 }
121 124
122 template<typename T> 125 template<typename T, typename A>
123 bool ReadVectorU8(std::vector<T>* items, SourceStream* buffer) { 126 bool ReadVectorU8(std::vector<T, A>* items, SourceStream* buffer) {
124 uint32 count; 127 uint32 count;
125 if (!buffer->ReadVarint32(&count)) 128 if (!buffer->ReadVarint32(&count))
126 return false; 129 return false;
127 130
128 items->clear(); 131 items->clear();
129 items->resize(count); 132 items->resize(count);
130 if (count != 0) { 133 if (count != 0) {
131 size_t byte_count = count * sizeof(T); 134 size_t byte_count = count * sizeof(T);
132 return buffer->Read(static_cast<void*>(&((*items)[0])), byte_count); 135 return buffer->Read(static_cast<void*>(&((*items)[0])), byte_count);
133 } 136 }
134 return true; 137 return true;
135 } 138 }
136 139
137 //////////////////////////////////////////////////////////////////////////////// 140 ////////////////////////////////////////////////////////////////////////////////
138 141
139 void EncodedProgram::DefineRel32Label(int index, RVA value) { 142 void EncodedProgram::DefineRel32Label(int index, RVA value) {
140 DefineLabelCommon(&rel32_rva_, index, value); 143 DefineLabelCommon(&rel32_rva_, index, value);
141 } 144 }
142 145
143 void EncodedProgram::DefineAbs32Label(int index, RVA value) { 146 void EncodedProgram::DefineAbs32Label(int index, RVA value) {
144 DefineLabelCommon(&abs32_rva_, index, value); 147 DefineLabelCommon(&abs32_rva_, index, value);
145 } 148 }
146 149
147 static const RVA kUnassignedRVA = static_cast<RVA>(-1); 150 static const RVA kUnassignedRVA = static_cast<RVA>(-1);
148 151
149 void EncodedProgram::DefineLabelCommon(std::vector<RVA>* rvas, 152 void EncodedProgram::DefineLabelCommon(RvaVector* rvas,
150 int index, 153 int index,
151 RVA rva) { 154 RVA rva) {
152 if (static_cast<int>(rvas->size()) <= index) { 155 if (static_cast<int>(rvas->size()) <= index) {
153 rvas->resize(index + 1, kUnassignedRVA); 156 rvas->resize(index + 1, kUnassignedRVA);
154 } 157 }
155 if ((*rvas)[index] != kUnassignedRVA) { 158 if ((*rvas)[index] != kUnassignedRVA) {
156 NOTREACHED() << "DefineLabel double assigned " << index; 159 NOTREACHED() << "DefineLabel double assigned " << index;
157 } 160 }
158 (*rvas)[index] = rva; 161 (*rvas)[index] = rva;
159 } 162 }
160 163
161 void EncodedProgram::EndLabels() { 164 void EncodedProgram::EndLabels() {
162 FinishLabelsCommon(&abs32_rva_); 165 FinishLabelsCommon(&abs32_rva_);
163 FinishLabelsCommon(&rel32_rva_); 166 FinishLabelsCommon(&rel32_rva_);
164 } 167 }
165 168
166 void EncodedProgram::FinishLabelsCommon(std::vector<RVA>* rvas) { 169 void EncodedProgram::FinishLabelsCommon(RvaVector* rvas) {
167 // Replace all unassigned slots with the value at the previous index so they 170 // Replace all unassigned slots with the value at the previous index so they
168 // delta-encode to zero. (There might be better values than zero. The way to 171 // delta-encode to zero. (There might be better values than zero. The way to
169 // get that is have the higher level assembly program assign the unassigned 172 // get that is have the higher level assembly program assign the unassigned
170 // slots.) 173 // slots.)
171 RVA previous = 0; 174 RVA previous = 0;
172 size_t size = rvas->size(); 175 size_t size = rvas->size();
173 for (size_t i = 0; i < size; ++i) { 176 for (size_t i = 0; i < size; ++i) {
174 if ((*rvas)[i] == kUnassignedRVA) 177 if ((*rvas)[i] == kUnassignedRVA)
175 (*rvas)[i] = previous; 178 (*rvas)[i] = previous;
176 else 179 else
177 previous = (*rvas)[i]; 180 previous = (*rvas)[i];
178 } 181 }
179 } 182 }
180 183
181 void EncodedProgram::AddOrigin(RVA origin) { 184 void EncodedProgram::AddOrigin(RVA origin) {
182 ops_.push_back(ORIGIN); 185 ops_.push_back(ORIGIN);
183 origins_.push_back(origin); 186 origins_.push_back(origin);
184 } 187 }
185 188
186 void EncodedProgram::AddCopy(int count, const void* bytes) { 189 void EncodedProgram::AddCopy(uint32 count, const void* bytes) {
187 const uint8* source = static_cast<const uint8*>(bytes); 190 const uint8* source = static_cast<const uint8*>(bytes);
188 191
189 // Fold adjacent COPY instructions into one. This nearly halves the size of 192 // Fold adjacent COPY instructions into one. This nearly halves the size of
190 // an EncodedProgram with only COPY1 instructions since there are approx plain 193 // an EncodedProgram with only COPY1 instructions since there are approx plain
191 // 16 bytes per reloc. This has a working-set benefit during decompression. 194 // 16 bytes per reloc. This has a working-set benefit during decompression.
192 // For compression of files with large differences this makes a small (4%) 195 // For compression of files with large differences this makes a small (4%)
193 // improvement in size. For files with small differences this degrades the 196 // improvement in size. For files with small differences this degrades the
194 // compressed size by 1.3% 197 // compressed size by 1.3%
195 if (ops_.size() > 0) { 198 if (ops_.size() > 0) {
196 if (ops_.back() == COPY1) { 199 if (ops_.back() == COPY1) {
197 ops_.back() = COPY; 200 ops_.back() = COPY;
198 copy_counts_.push_back(1); 201 copy_counts_.push_back(1);
199 } 202 }
200 if (ops_.back() == COPY) { 203 if (ops_.back() == COPY) {
201 copy_counts_.back() += count; 204 copy_counts_.back() += count;
202 for (int i = 0; i < count; ++i) { 205 for (uint32 i = 0; i < count; ++i) {
203 copy_bytes_.push_back(source[i]); 206 copy_bytes_.push_back(source[i]);
204 } 207 }
205 return; 208 return;
206 } 209 }
207 } 210 }
208 211
209 if (count == 1) { 212 if (count == 1) {
210 ops_.push_back(COPY1); 213 ops_.push_back(COPY1);
211 copy_bytes_.push_back(source[0]); 214 copy_bytes_.push_back(source[0]);
212 } else { 215 } else {
213 ops_.push_back(COPY); 216 ops_.push_back(COPY);
214 copy_counts_.push_back(count); 217 copy_counts_.push_back(count);
215 for (int i = 0; i < count; ++i) { 218 for (uint32 i = 0; i < count; ++i) {
216 copy_bytes_.push_back(source[i]); 219 copy_bytes_.push_back(source[i]);
217 } 220 }
218 } 221 }
219 } 222 }
220 223
221 void EncodedProgram::AddAbs32(int label_index) { 224 void EncodedProgram::AddAbs32(int label_index) {
222 ops_.push_back(ABS32); 225 ops_.push_back(ABS32);
223 abs32_ix_.push_back(label_index); 226 abs32_ix_.push_back(label_index);
224 } 227 }
225 228
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 for (int i = 0; i < kStreamLimit; ++i) { 345 for (int i = 0; i < kStreamLimit; ++i) {
343 if (streams->stream(i)->Remaining() > 0) 346 if (streams->stream(i)->Remaining() > 0)
344 return false; 347 return false;
345 } 348 }
346 349
347 return true; 350 return true;
348 } 351 }
349 352
350 // Safe, non-throwing version of std::vector::at(). Returns 'true' for success, 353 // Safe, non-throwing version of std::vector::at(). Returns 'true' for success,
351 // 'false' for out-of-bounds index error. 354 // 'false' for out-of-bounds index error.
352 template<typename T> 355 template<typename T, typename A>
353 bool VectorAt(const std::vector<T>& v, size_t index, T* output) { 356 bool VectorAt(const std::vector<T, A>& v, size_t index, T* output) {
354 if (index >= v.size()) 357 if (index >= v.size())
355 return false; 358 return false;
356 *output = v[index]; 359 *output = v[index];
357 return true; 360 return true;
358 } 361 }
359 362
360 bool EncodedProgram::AssembleTo(SinkStream* final_buffer) { 363 bool EncodedProgram::AssembleTo(SinkStream* final_buffer) {
361 // For the most part, the assembly process walks the various tables. 364 // For the most part, the assembly process walks the various tables.
362 // ix_mumble is the index into the mumble table. 365 // ix_mumble is the index into the mumble table.
363 size_t ix_origins = 0; 366 size_t ix_origins = 0;
(...skipping 19 matching lines...) Expand all
383 case ORIGIN: { 386 case ORIGIN: {
384 RVA section_rva; 387 RVA section_rva;
385 if (!VectorAt(origins_, ix_origins, &section_rva)) 388 if (!VectorAt(origins_, ix_origins, &section_rva))
386 return false; 389 return false;
387 ++ix_origins; 390 ++ix_origins;
388 current_rva = section_rva; 391 current_rva = section_rva;
389 break; 392 break;
390 } 393 }
391 394
392 case COPY: { 395 case COPY: {
393 int count; 396 uint32 count;
394 if (!VectorAt(copy_counts_, ix_copy_counts, &count)) 397 if (!VectorAt(copy_counts_, ix_copy_counts, &count))
395 return false; 398 return false;
396 ++ix_copy_counts; 399 ++ix_copy_counts;
397 for (int i = 0; i < count; ++i) { 400 for (uint32 i = 0; i < count; ++i) {
398 uint8 b; 401 uint8 b;
399 if (!VectorAt(copy_bytes_, ix_copy_bytes, &b)) 402 if (!VectorAt(copy_bytes_, ix_copy_bytes, &b))
400 return false; 403 return false;
401 ++ix_copy_bytes; 404 ++ix_copy_bytes;
402 output->Write(&b, 1); 405 output->Write(&b, 1);
403 } 406 }
404 current_rva += count; 407 current_rva += count;
405 break; 408 break;
406 } 409 }
407 410
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 if (assembled) 563 if (assembled)
561 return C_OK; 564 return C_OK;
562 return C_ASSEMBLY_FAILED; 565 return C_ASSEMBLY_FAILED;
563 } 566 }
564 567
565 void DeleteEncodedProgram(EncodedProgram* encoded) { 568 void DeleteEncodedProgram(EncodedProgram* encoded) {
566 delete encoded; 569 delete encoded;
567 } 570 }
568 571
569 } // end namespace 572 } // end namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698