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

Side by Side Diff: src/liveedit.cc

Issue 7087031: LiveEdit: Optimize compare by stripping common suffix and prefix. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: format Created 9 years, 6 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 | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 Handle<String> s2, int pos2, int len) { 272 Handle<String> s2, int pos2, int len) {
273 for (int i = 0; i < len; i++) { 273 for (int i = 0; i < len; i++) {
274 if (s1->Get(i + pos1) != s2->Get(i + pos2)) { 274 if (s1->Get(i + pos1) != s2->Get(i + pos2)) {
275 return false; 275 return false;
276 } 276 }
277 } 277 }
278 return true; 278 return true;
279 } 279 }
280 280
281 281
282 // Additional to Input interface. Lets switch Input range to subrange.
283 // More elegant way would be to wrap one Input as another Input object
284 // and translate positions there, but that would cost us additional virtual
285 // call per comparison.
286 class SubrangableInput : public Comparator::Input {
287 public:
288 virtual void setSubrange1(int offset, int len) = 0;
Søren Thygesen Gjesse 2011/05/31 08:09:19 set -> Set (times 4)
Peter Rybin 2011/05/31 15:02:23 Oh sorry, cannot properly switch to C++ again. :(
289 virtual void setSubrange2(int offset, int len) = 0;
290 };
291
292
293 class SubrangableOutput : public Comparator::Output {
294 public:
295 virtual void setSubrange1(int offset, int len) = 0;
296 virtual void setSubrange2(int offset, int len) = 0;
297 };
298
299
300 static int min(int a, int b) {
301 return a < b ? a : b;
302 }
303
304
305 // Finds common prefix and suffix in input. This parts shouldn't take space in
306 // linear programming table. Enable subranging in input and output.
307 static void NarrowDownInput(SubrangableInput* input,
308 SubrangableOutput* output) {
309 const int len1 = input->getLength1();
310 const int len2 = input->getLength2();
311
312 int common_prefix_len;
313 int common_suffix_len;
314
315 {
316 common_prefix_len = 0;
317 int prefix_limit = min(len1, len2);
318 while (common_prefix_len < prefix_limit &&
319 input->equals(common_prefix_len, common_prefix_len)) {
320 common_prefix_len++;
321 }
322
323 common_suffix_len = 0;
324 int suffix_limit = min(len1 - common_prefix_len, len2 - common_prefix_len);
325
326 while (common_suffix_len < suffix_limit &&
327 input->equals(len1 - common_suffix_len - 1,
328 len2 - common_suffix_len - 1)) {
329 common_suffix_len++;
330 }
331 }
332
333 if (common_prefix_len > 0 || common_suffix_len) {
Søren Thygesen Gjesse 2011/05/31 08:09:19 common_suffix_len -> common_suffix_len > 0
Peter Rybin 2011/05/31 15:02:23 Thanks, missed this! Done
334 int new_len1 = len1 - common_suffix_len - common_prefix_len;
335 int new_len2 = len2 - common_suffix_len - common_prefix_len;
336
337 input->setSubrange1(common_prefix_len, new_len1);
338 input->setSubrange2(common_prefix_len, new_len2);
339
340 output->setSubrange1(common_prefix_len, new_len1);
341 output->setSubrange2(common_prefix_len, new_len2);
342 }
343 }
344
345
282 // A helper class that writes chunk numbers into JSArray. 346 // A helper class that writes chunk numbers into JSArray.
283 // Each chunk is stored as 3 array elements: (pos1_begin, pos1_end, pos2_end). 347 // Each chunk is stored as 3 array elements: (pos1_begin, pos1_end, pos2_end).
284 class CompareOutputArrayWriter { 348 class CompareOutputArrayWriter {
285 public: 349 public:
286 CompareOutputArrayWriter() 350 CompareOutputArrayWriter()
287 : array_(FACTORY->NewJSArray(10)), current_size_(0) {} 351 : array_(FACTORY->NewJSArray(10)), current_size_(0) {}
288 352
289 Handle<JSArray> GetResult() { 353 Handle<JSArray> GetResult() {
290 return array_; 354 return array_;
291 } 355 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 Handle<FixedArray> ends_array_; 458 Handle<FixedArray> ends_array_;
395 int string_len_; 459 int string_len_;
396 460
397 int GetPosAfterNewLine(int index) { 461 int GetPosAfterNewLine(int index) {
398 return Smi::cast(ends_array_->get(index))->value() + 1; 462 return Smi::cast(ends_array_->get(index))->value() + 1;
399 } 463 }
400 }; 464 };
401 465
402 466
403 // Represents 2 strings as 2 arrays of lines. 467 // Represents 2 strings as 2 arrays of lines.
404 class LineArrayCompareInput : public Comparator::Input { 468 class LineArrayCompareInput : public SubrangableInput {
405 public: 469 public:
406 LineArrayCompareInput(Handle<String> s1, Handle<String> s2, 470 LineArrayCompareInput(Handle<String> s1, Handle<String> s2,
407 LineEndsWrapper line_ends1, LineEndsWrapper line_ends2) 471 LineEndsWrapper line_ends1, LineEndsWrapper line_ends2)
408 : s1_(s1), s2_(s2), line_ends1_(line_ends1), 472 : s1_(s1), s2_(s2), line_ends1_(line_ends1),
409 line_ends2_(line_ends2) { 473 line_ends2_(line_ends2),
474 subrange_offset1_(0), subrange_offset2_(0),
475 subrange_len1_(line_ends1_.length()),
476 subrange_len2_(line_ends2_.length()) {
410 } 477 }
411 int getLength1() { 478 int getLength1() {
Søren Thygesen Gjesse 2011/05/31 08:09:19 get -> Get
Peter Rybin 2011/05/31 15:02:23 Done.
412 return line_ends1_.length(); 479 return subrange_len1_;
413 } 480 }
414 int getLength2() { 481 int getLength2() {
415 return line_ends2_.length(); 482 return subrange_len2_;
416 } 483 }
417 bool equals(int index1, int index2) { 484 bool equals(int index1, int index2) {
Søren Thygesen Gjesse 2011/05/31 08:09:19 equals -> Equals
Peter Rybin 2011/05/31 15:02:23 Done.
485 index1 += subrange_offset1_;
486 index2 += subrange_offset2_;
487
418 int line_start1 = line_ends1_.GetLineStart(index1); 488 int line_start1 = line_ends1_.GetLineStart(index1);
419 int line_start2 = line_ends2_.GetLineStart(index2); 489 int line_start2 = line_ends2_.GetLineStart(index2);
420 int line_end1 = line_ends1_.GetLineEnd(index1); 490 int line_end1 = line_ends1_.GetLineEnd(index1);
421 int line_end2 = line_ends2_.GetLineEnd(index2); 491 int line_end2 = line_ends2_.GetLineEnd(index2);
422 int len1 = line_end1 - line_start1; 492 int len1 = line_end1 - line_start1;
423 int len2 = line_end2 - line_start2; 493 int len2 = line_end2 - line_start2;
424 if (len1 != len2) { 494 if (len1 != len2) {
425 return false; 495 return false;
426 } 496 }
427 return CompareSubstrings(s1_, line_start1, s2_, line_start2, 497 return CompareSubstrings(s1_, line_start1, s2_, line_start2,
428 len1); 498 len1);
429 } 499 }
500 void setSubrange1(int offset, int len) {
501 subrange_offset1_ = offset;
502 subrange_len1_ = len;
503 }
504 void setSubrange2(int offset, int len) {
505 subrange_offset2_ = offset;
506 subrange_len2_ = len;
507 }
430 508
431 private: 509 private:
432 Handle<String> s1_; 510 Handle<String> s1_;
433 Handle<String> s2_; 511 Handle<String> s2_;
434 LineEndsWrapper line_ends1_; 512 LineEndsWrapper line_ends1_;
435 LineEndsWrapper line_ends2_; 513 LineEndsWrapper line_ends2_;
514 int subrange_offset1_;
515 int subrange_offset2_;
516 int subrange_len1_;
517 int subrange_len2_;
436 }; 518 };
437 519
438 520
439 // Stores compare result in JSArray. For each chunk tries to conduct 521 // Stores compare result in JSArray. For each chunk tries to conduct
440 // a fine-grained nested diff token-wise. 522 // a fine-grained nested diff token-wise.
441 class TokenizingLineArrayCompareOutput : public Comparator::Output { 523 class TokenizingLineArrayCompareOutput : public SubrangableOutput {
442 public: 524 public:
443 TokenizingLineArrayCompareOutput(LineEndsWrapper line_ends1, 525 TokenizingLineArrayCompareOutput(LineEndsWrapper line_ends1,
444 LineEndsWrapper line_ends2, 526 LineEndsWrapper line_ends2,
445 Handle<String> s1, Handle<String> s2) 527 Handle<String> s1, Handle<String> s2)
446 : line_ends1_(line_ends1), line_ends2_(line_ends2), s1_(s1), s2_(s2) { 528 : line_ends1_(line_ends1), line_ends2_(line_ends2), s1_(s1), s2_(s2),
529 subrange_offset1_(0), subrange_offset2_(0) {
447 } 530 }
448 531
449 void AddChunk(int line_pos1, int line_pos2, int line_len1, int line_len2) { 532 void AddChunk(int line_pos1, int line_pos2, int line_len1, int line_len2) {
533 line_pos1 += subrange_offset1_;
534 line_pos2 += subrange_offset2_;
535
450 int char_pos1 = line_ends1_.GetLineStart(line_pos1); 536 int char_pos1 = line_ends1_.GetLineStart(line_pos1);
451 int char_pos2 = line_ends2_.GetLineStart(line_pos2); 537 int char_pos2 = line_ends2_.GetLineStart(line_pos2);
452 int char_len1 = line_ends1_.GetLineStart(line_pos1 + line_len1) - char_pos1; 538 int char_len1 = line_ends1_.GetLineStart(line_pos1 + line_len1) - char_pos1;
453 int char_len2 = line_ends2_.GetLineStart(line_pos2 + line_len2) - char_pos2; 539 int char_len2 = line_ends2_.GetLineStart(line_pos2 + line_len2) - char_pos2;
454 540
455 if (char_len1 < CHUNK_LEN_LIMIT && char_len2 < CHUNK_LEN_LIMIT) { 541 if (char_len1 < CHUNK_LEN_LIMIT && char_len2 < CHUNK_LEN_LIMIT) {
456 // Chunk is small enough to conduct a nested token-level diff. 542 // Chunk is small enough to conduct a nested token-level diff.
457 HandleScope subTaskScope; 543 HandleScope subTaskScope;
458 544
459 TokensCompareInput tokens_input(s1_, char_pos1, char_len1, 545 TokensCompareInput tokens_input(s1_, char_pos1, char_len1,
460 s2_, char_pos2, char_len2); 546 s2_, char_pos2, char_len2);
461 TokensCompareOutput tokens_output(&array_writer_, char_pos1, 547 TokensCompareOutput tokens_output(&array_writer_, char_pos1,
462 char_pos2); 548 char_pos2);
463 549
464 Comparator::CalculateDifference(&tokens_input, &tokens_output); 550 Comparator::CalculateDifference(&tokens_input, &tokens_output);
465 } else { 551 } else {
466 array_writer_.WriteChunk(char_pos1, char_pos2, char_len1, char_len2); 552 array_writer_.WriteChunk(char_pos1, char_pos2, char_len1, char_len2);
467 } 553 }
468 } 554 }
555 void setSubrange1(int offset, int len) {
556 subrange_offset1_ = offset;
557 }
558 void setSubrange2(int offset, int len) {
559 subrange_offset2_ = offset;
560 }
469 561
470 Handle<JSArray> GetResult() { 562 Handle<JSArray> GetResult() {
471 return array_writer_.GetResult(); 563 return array_writer_.GetResult();
472 } 564 }
473 565
474 private: 566 private:
475 static const int CHUNK_LEN_LIMIT = 800; 567 static const int CHUNK_LEN_LIMIT = 800;
476 568
477 CompareOutputArrayWriter array_writer_; 569 CompareOutputArrayWriter array_writer_;
478 LineEndsWrapper line_ends1_; 570 LineEndsWrapper line_ends1_;
479 LineEndsWrapper line_ends2_; 571 LineEndsWrapper line_ends2_;
480 Handle<String> s1_; 572 Handle<String> s1_;
481 Handle<String> s2_; 573 Handle<String> s2_;
574 int subrange_offset1_;
575 int subrange_offset2_;
482 }; 576 };
483 577
484 578
485 Handle<JSArray> LiveEdit::CompareStrings(Handle<String> s1, 579 Handle<JSArray> LiveEdit::CompareStrings(Handle<String> s1,
486 Handle<String> s2) { 580 Handle<String> s2) {
487 s1 = FlattenGetString(s1); 581 s1 = FlattenGetString(s1);
488 s2 = FlattenGetString(s2); 582 s2 = FlattenGetString(s2);
489 583
490 LineEndsWrapper line_ends1(s1); 584 LineEndsWrapper line_ends1(s1);
491 LineEndsWrapper line_ends2(s2); 585 LineEndsWrapper line_ends2(s2);
492 586
493 LineArrayCompareInput input(s1, s2, line_ends1, line_ends2); 587 LineArrayCompareInput input(s1, s2, line_ends1, line_ends2);
494 TokenizingLineArrayCompareOutput output(line_ends1, line_ends2, s1, s2); 588 TokenizingLineArrayCompareOutput output(line_ends1, line_ends2, s1, s2);
495 589
590 NarrowDownInput(&input, &output);
591
496 Comparator::CalculateDifference(&input, &output); 592 Comparator::CalculateDifference(&input, &output);
497 593
498 return output.GetResult(); 594 return output.GetResult();
499 } 595 }
500 596
501 597
502 static void CompileScriptForTracker(Isolate* isolate, Handle<Script> script) { 598 static void CompileScriptForTracker(Isolate* isolate, Handle<Script> script) {
503 // TODO(635): support extensions. 599 // TODO(635): support extensions.
504 PostponeInterruptsScope postpone(isolate); 600 PostponeInterruptsScope postpone(isolate);
505 601
(...skipping 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 1778
1683 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) { 1779 bool LiveEditFunctionTracker::IsActive(Isolate* isolate) {
1684 return false; 1780 return false;
1685 } 1781 }
1686 1782
1687 #endif // ENABLE_DEBUGGER_SUPPORT 1783 #endif // ENABLE_DEBUGGER_SUPPORT
1688 1784
1689 1785
1690 1786
1691 } } // namespace v8::internal 1787 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698