OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |