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

Side by Side Diff: src/hydrogen-load-elimination.cc

Issue 28383003: Handle misaligned loads and stores in load elimination. Do not track misaligned loads and be conser… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 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
« no previous file with comments | « no previous file | test/mjsunit/number-tostring-add.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 return approx->last_value_; 205 return approx->last_value_;
206 } 206 }
207 } 207 }
208 208
209 // Process a store instruction, updating internal table state. If a previous 209 // Process a store instruction, updating internal table state. If a previous
210 // store to the same object and field makes this store redundant (e.g. because 210 // store to the same object and field makes this store redundant (e.g. because
211 // the stored values are the same), return NULL indicating that this store 211 // the stored values are the same), return NULL indicating that this store
212 // instruction is redundant. Otherwise, return {instr}. 212 // instruction is redundant. Otherwise, return {instr}.
213 HValue* store(HStoreNamedField* instr) { 213 HValue* store(HStoreNamedField* instr) {
214 int field = FieldOf(instr->access()); 214 int field = FieldOf(instr->access());
215 if (field < 0) return instr; 215 if (field < 0) return KillIfMisaligned(instr);
216 216
217 HValue* object = instr->object()->ActualValue(); 217 HValue* object = instr->object()->ActualValue();
218 HValue* value = instr->value(); 218 HValue* value = instr->value();
219 219
220 // Kill non-equivalent may-alias entries. 220 // Kill non-equivalent may-alias entries.
221 KillFieldInternal(object, field, value); 221 KillFieldInternal(object, field, value);
222 if (instr->has_transition()) { 222 if (instr->has_transition()) {
223 // A transition store alters the map of the object. 223 // A transition store alters the map of the object.
224 // TODO(titzer): remember the new map (a constant) for the object. 224 // TODO(titzer): remember the new map (a constant) for the object.
225 KillFieldInternal(object, FieldOf(JSObject::kMapOffset), NULL); 225 KillFieldInternal(object, FieldOf(JSObject::kMapOffset), NULL);
(...skipping 17 matching lines...) Expand all
243 } 243 }
244 244
245 // Kill all entries matching the given offset. 245 // Kill all entries matching the given offset.
246 void KillOffset(int offset) { 246 void KillOffset(int offset) {
247 int field = FieldOf(offset); 247 int field = FieldOf(offset);
248 if (field >= 0 && field < fields_.length()) { 248 if (field >= 0 && field < fields_.length()) {
249 fields_[field] = NULL; 249 fields_[field] = NULL;
250 } 250 }
251 } 251 }
252 252
253 // Kill all entries aliasing the given store.
254 void KillStore(HStoreNamedField* s) {
255 int field = FieldOf(s->access());
256 if (field >= 0) {
257 KillFieldInternal(s->object()->ActualValue(), field, s->value());
258 } else {
259 KillIfMisaligned(s);
260 }
261 }
262
263 // Kill multiple entries in the case of a misaligned store.
264 HValue* KillIfMisaligned(HStoreNamedField* instr) {
265 HObjectAccess access = instr->access();
266 if (access.IsInobject()) {
267 int offset = access.offset();
268 if ((offset % kPointerSize) != 0) {
269 // Kill the field containing the first word of the access.
270 HValue* object = instr->object()->ActualValue();
271 int field = offset / kPointerSize;
272 KillFieldInternal(object, field, NULL);
273
274 // Kill the next field in case of overlap.
275 int size = kPointerSize;
276 if (access.representation().IsByte()) size = 1;
277 else if (access.representation().IsInteger32()) size = 4;
278 int next_field = (offset + size - 1) / kPointerSize;
279 if (next_field != field) KillFieldInternal(object, next_field, NULL);
280 }
281 }
282 return instr;
283 }
284
253 // Find an entry for the given object and field pair. 285 // Find an entry for the given object and field pair.
254 HFieldApproximation* Find(HValue* object, int field) { 286 HFieldApproximation* Find(HValue* object, int field) {
255 // Search for a field approximation for this object. 287 // Search for a field approximation for this object.
256 HFieldApproximation* approx = fields_[field]; 288 HFieldApproximation* approx = fields_[field];
257 while (approx != NULL) { 289 while (approx != NULL) {
258 if (aliasing_->MustAlias(object, approx->object_)) return approx; 290 if (aliasing_->MustAlias(object, approx->object_)) return approx;
259 approx = approx->next_; 291 approx = approx->next_;
260 } 292 }
261 return NULL; 293 return NULL;
262 } 294 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 } 372 }
341 373
342 // Compute the field index for the given object access; -1 if not tracked. 374 // Compute the field index for the given object access; -1 if not tracked.
343 int FieldOf(HObjectAccess access) { 375 int FieldOf(HObjectAccess access) {
344 return access.IsInobject() ? FieldOf(access.offset()) : -1; 376 return access.IsInobject() ? FieldOf(access.offset()) : -1;
345 } 377 }
346 378
347 // Compute the field index for the given in-object offset; -1 if not tracked. 379 // Compute the field index for the given in-object offset; -1 if not tracked.
348 int FieldOf(int offset) { 380 int FieldOf(int offset) {
349 if (offset >= kMaxTrackedFields * kPointerSize) return -1; 381 if (offset >= kMaxTrackedFields * kPointerSize) return -1;
350 ASSERT((offset % kPointerSize) == 0); // Assume aligned accesses. 382 // TODO(titzer): track misaligned loads in a separate list?
383 if ((offset % kPointerSize) != 0) return -1; // Ignore misaligned accesses.
351 return offset / kPointerSize; 384 return offset / kPointerSize;
352 } 385 }
353 386
354 // Ensure internal storage for the given number of fields. 387 // Ensure internal storage for the given number of fields.
355 void EnsureFields(int num_fields) { 388 void EnsureFields(int num_fields) {
356 if (fields_.length() < num_fields) { 389 if (fields_.length() < num_fields) {
357 fields_.AddBlock(NULL, num_fields - fields_.length(), zone_); 390 fields_.AddBlock(NULL, num_fields - fields_.length(), zone_);
358 } 391 }
359 } 392 }
360 393
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 } 456 }
424 if (maps_stored_) { 457 if (maps_stored_) {
425 table->KillOffset(JSObject::kMapOffset); 458 table->KillOffset(JSObject::kMapOffset);
426 } 459 }
427 if (elements_stored_) { 460 if (elements_stored_) {
428 table->KillOffset(JSObject::kElementsOffset); 461 table->KillOffset(JSObject::kElementsOffset);
429 } 462 }
430 463
431 // Kill non-agreeing fields for each store contained in these effects. 464 // Kill non-agreeing fields for each store contained in these effects.
432 for (int i = 0; i < stores_.length(); i++) { 465 for (int i = 0; i < stores_.length(); i++) {
433 HStoreNamedField* s = stores_[i]; 466 table->KillStore(stores_[i]);
434 int field = table->FieldOf(s->access());
435 if (field >= 0) {
436 table->KillFieldInternal(s->object()->ActualValue(), field, s->value());
437 }
438 } 467 }
439 } 468 }
440 469
441 // Union these effects with the other effects. 470 // Union these effects with the other effects.
442 void Union(HLoadEliminationEffects* that, Zone* zone) { 471 void Union(HLoadEliminationEffects* that, Zone* zone) {
443 maps_stored_ |= that->maps_stored_; 472 maps_stored_ |= that->maps_stored_;
444 fields_stored_ |= that->fields_stored_; 473 fields_stored_ |= that->fields_stored_;
445 elements_stored_ |= that->elements_stored_; 474 elements_stored_ |= that->elements_stored_;
446 for (int i = 0; i < that->stores_.length(); i++) { 475 for (int i = 0; i < that->stores_.length(); i++) {
447 stores_.Add(that->stores_[i], zone); 476 stores_.Add(that->stores_[i], zone);
(...skipping 24 matching lines...) Expand all
472 } else { 501 } else {
473 // Perform only local analysis. 502 // Perform only local analysis.
474 for (int i = 0; i < graph()->blocks()->length(); i++) { 503 for (int i = 0; i < graph()->blocks()->length(); i++) {
475 table->Kill(); 504 table->Kill();
476 engine.AnalyzeOneBlock(graph()->blocks()->at(i), table); 505 engine.AnalyzeOneBlock(graph()->blocks()->at(i), table);
477 } 506 }
478 } 507 }
479 } 508 }
480 509
481 } } // namespace v8::internal 510 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/number-tostring-add.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698