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

Side by Side Diff: src/ia32/macro-assembler-ia32.cc

Issue 9227007: Version 3.8.6 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 11 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 | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2012 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
11 // with the distribution. 11 // with the distribution.
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 } else { 480 } else {
481 push(scratch1); 481 push(scratch1);
482 fild_s(Operand(esp, 0)); 482 fild_s(Operand(esp, 0));
483 pop(scratch1); 483 pop(scratch1);
484 fstp_d(FieldOperand(elements, key, times_4, FixedDoubleArray::kHeaderSize)); 484 fstp_d(FieldOperand(elements, key, times_4, FixedDoubleArray::kHeaderSize));
485 } 485 }
486 bind(&done); 486 bind(&done);
487 } 487 }
488 488
489 489
490 void MacroAssembler::CompareMap(Register obj,
491 Handle<Map> map,
492 Label* early_success,
493 CompareMapMode mode) {
494 cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
495 if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
496 Map* transitioned_fast_element_map(
497 map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL));
498 ASSERT(transitioned_fast_element_map == NULL ||
499 map->elements_kind() != FAST_ELEMENTS);
500 if (transitioned_fast_element_map != NULL) {
501 j(equal, early_success, Label::kNear);
502 cmp(FieldOperand(obj, HeapObject::kMapOffset),
503 Handle<Map>(transitioned_fast_element_map));
504 }
505
506 Map* transitioned_double_map(
507 map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL));
508 ASSERT(transitioned_double_map == NULL ||
509 map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
510 if (transitioned_double_map != NULL) {
511 j(equal, early_success, Label::kNear);
512 cmp(FieldOperand(obj, HeapObject::kMapOffset),
513 Handle<Map>(transitioned_double_map));
514 }
515 }
516 }
517
518
490 void MacroAssembler::CheckMap(Register obj, 519 void MacroAssembler::CheckMap(Register obj,
491 Handle<Map> map, 520 Handle<Map> map,
492 Label* fail, 521 Label* fail,
493 SmiCheckType smi_check_type) { 522 SmiCheckType smi_check_type,
523 CompareMapMode mode) {
494 if (smi_check_type == DO_SMI_CHECK) { 524 if (smi_check_type == DO_SMI_CHECK) {
495 JumpIfSmi(obj, fail); 525 JumpIfSmi(obj, fail);
496 } 526 }
497 cmp(FieldOperand(obj, HeapObject::kMapOffset), Immediate(map)); 527
528 Label success;
529 CompareMap(obj, map, &success, mode);
498 j(not_equal, fail); 530 j(not_equal, fail);
531 bind(&success);
499 } 532 }
500 533
501 534
502 void MacroAssembler::DispatchMap(Register obj, 535 void MacroAssembler::DispatchMap(Register obj,
503 Handle<Map> map, 536 Handle<Map> map,
504 Handle<Code> success, 537 Handle<Code> success,
505 SmiCheckType smi_check_type) { 538 SmiCheckType smi_check_type) {
506 Label fail; 539 Label fail;
507 if (smi_check_type == DO_SMI_CHECK) { 540 if (smi_check_type == DO_SMI_CHECK) {
508 JumpIfSmi(obj, &fail); 541 JumpIfSmi(obj, &fail);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 if (emit_debug_code()) { 642 if (emit_debug_code()) {
610 cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset), 643 cmp(Operand(ebp, StandardFrameConstants::kMarkerOffset),
611 Immediate(Smi::FromInt(type))); 644 Immediate(Smi::FromInt(type)));
612 Check(equal, "stack frame types must match"); 645 Check(equal, "stack frame types must match");
613 } 646 }
614 leave(); 647 leave();
615 } 648 }
616 649
617 650
618 void MacroAssembler::EnterExitFramePrologue() { 651 void MacroAssembler::EnterExitFramePrologue() {
619 // Setup the frame structure on the stack. 652 // Set up the frame structure on the stack.
620 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); 653 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize);
621 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); 654 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize);
622 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 655 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize);
623 push(ebp); 656 push(ebp);
624 mov(ebp, esp); 657 mov(ebp, esp);
625 658
626 // Reserve room for entry stack pointer and push the code object. 659 // Reserve room for entry stack pointer and push the code object.
627 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 660 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
628 push(Immediate(0)); // Saved entry sp, patched before call. 661 push(Immediate(0)); // Saved entry sp, patched before call.
629 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. 662 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 } 694 }
662 695
663 // Patch the saved entry sp. 696 // Patch the saved entry sp.
664 mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); 697 mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp);
665 } 698 }
666 699
667 700
668 void MacroAssembler::EnterExitFrame(bool save_doubles) { 701 void MacroAssembler::EnterExitFrame(bool save_doubles) {
669 EnterExitFramePrologue(); 702 EnterExitFramePrologue();
670 703
671 // Setup argc and argv in callee-saved registers. 704 // Set up argc and argv in callee-saved registers.
672 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 705 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
673 mov(edi, eax); 706 mov(edi, eax);
674 lea(esi, Operand(ebp, eax, times_4, offset)); 707 lea(esi, Operand(ebp, eax, times_4, offset));
675 708
676 // Reserve space for argc, argv and isolate. 709 // Reserve space for argc, argv and isolate.
677 EnterExitFrameEpilogue(3, save_doubles); 710 EnterExitFrameEpilogue(3, save_doubles);
678 } 711 }
679 712
680 713
681 void MacroAssembler::EnterApiExitFrame(int argc) { 714 void MacroAssembler::EnterApiExitFrame(int argc) {
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 Context::SECURITY_TOKEN_INDEX * kPointerSize; 985 Context::SECURITY_TOKEN_INDEX * kPointerSize;
953 mov(scratch, FieldOperand(scratch, token_offset)); 986 mov(scratch, FieldOperand(scratch, token_offset));
954 cmp(scratch, FieldOperand(holder_reg, token_offset)); 987 cmp(scratch, FieldOperand(holder_reg, token_offset));
955 pop(holder_reg); 988 pop(holder_reg);
956 j(not_equal, miss); 989 j(not_equal, miss);
957 990
958 bind(&same_contexts); 991 bind(&same_contexts);
959 } 992 }
960 993
961 994
995 // Compute the hash code from the untagged key. This must be kept in sync
996 // with ComputeIntegerHash in utils.h.
997 //
998 // Note: r0 will contain hash code
999 void MacroAssembler::GetNumberHash(Register r0, Register scratch) {
1000 // Xor original key with a seed.
1001 if (Serializer::enabled()) {
1002 ExternalReference roots_array_start =
1003 ExternalReference::roots_array_start(isolate());
1004 mov(scratch, Immediate(Heap::kHashSeedRootIndex));
1005 mov(scratch,
1006 Operand::StaticArray(scratch, times_pointer_size, roots_array_start));
1007 SmiUntag(scratch);
1008 xor_(r0, scratch);
1009 } else {
1010 int32_t seed = isolate()->heap()->HashSeed();
1011 xor_(r0, Immediate(seed));
1012 }
1013
1014 // hash = ~hash + (hash << 15);
1015 mov(scratch, r0);
1016 not_(r0);
1017 shl(scratch, 15);
1018 add(r0, scratch);
1019 // hash = hash ^ (hash >> 12);
1020 mov(scratch, r0);
1021 shr(scratch, 12);
1022 xor_(r0, scratch);
1023 // hash = hash + (hash << 2);
1024 lea(r0, Operand(r0, r0, times_4, 0));
1025 // hash = hash ^ (hash >> 4);
1026 mov(scratch, r0);
1027 shr(scratch, 4);
1028 xor_(r0, scratch);
1029 // hash = hash * 2057;
1030 imul(r0, r0, 2057);
1031 // hash = hash ^ (hash >> 16);
1032 mov(scratch, r0);
1033 shr(scratch, 16);
1034 xor_(r0, scratch);
1035 }
1036
1037
1038
962 void MacroAssembler::LoadFromNumberDictionary(Label* miss, 1039 void MacroAssembler::LoadFromNumberDictionary(Label* miss,
963 Register elements, 1040 Register elements,
964 Register key, 1041 Register key,
965 Register r0, 1042 Register r0,
966 Register r1, 1043 Register r1,
967 Register r2, 1044 Register r2,
968 Register result) { 1045 Register result) {
969 // Register use: 1046 // Register use:
970 // 1047 //
971 // elements - holds the slow-case elements of the receiver and is unchanged. 1048 // elements - holds the slow-case elements of the receiver and is unchanged.
972 // 1049 //
973 // key - holds the smi key on entry and is unchanged. 1050 // key - holds the smi key on entry and is unchanged.
974 // 1051 //
975 // Scratch registers: 1052 // Scratch registers:
976 // 1053 //
977 // r0 - holds the untagged key on entry and holds the hash once computed. 1054 // r0 - holds the untagged key on entry and holds the hash once computed.
978 // 1055 //
979 // r1 - used to hold the capacity mask of the dictionary 1056 // r1 - used to hold the capacity mask of the dictionary
980 // 1057 //
981 // r2 - used for the index into the dictionary. 1058 // r2 - used for the index into the dictionary.
982 // 1059 //
983 // result - holds the result on exit if the load succeeds and we fall through. 1060 // result - holds the result on exit if the load succeeds and we fall through.
984 1061
985 Label done; 1062 Label done;
986 1063
987 // Compute the hash code from the untagged key. This must be kept in sync 1064 GetNumberHash(r0, r1);
988 // with ComputeIntegerHash in utils.h.
989 //
990 // hash = ~hash + (hash << 15);
991 mov(r1, r0);
992 not_(r0);
993 shl(r1, 15);
994 add(r0, r1);
995 // hash = hash ^ (hash >> 12);
996 mov(r1, r0);
997 shr(r1, 12);
998 xor_(r0, r1);
999 // hash = hash + (hash << 2);
1000 lea(r0, Operand(r0, r0, times_4, 0));
1001 // hash = hash ^ (hash >> 4);
1002 mov(r1, r0);
1003 shr(r1, 4);
1004 xor_(r0, r1);
1005 // hash = hash * 2057;
1006 imul(r0, r0, 2057);
1007 // hash = hash ^ (hash >> 16);
1008 mov(r1, r0);
1009 shr(r1, 16);
1010 xor_(r0, r1);
1011 1065
1012 // Compute capacity mask. 1066 // Compute capacity mask.
1013 mov(r1, FieldOperand(elements, NumberDictionary::kCapacityOffset)); 1067 mov(r1, FieldOperand(elements, SeededNumberDictionary::kCapacityOffset));
1014 shr(r1, kSmiTagSize); // convert smi to int 1068 shr(r1, kSmiTagSize); // convert smi to int
1015 dec(r1); 1069 dec(r1);
1016 1070
1017 // Generate an unrolled loop that performs a few probes before giving up. 1071 // Generate an unrolled loop that performs a few probes before giving up.
1018 const int kProbes = 4; 1072 const int kProbes = 4;
1019 for (int i = 0; i < kProbes; i++) { 1073 for (int i = 0; i < kProbes; i++) {
1020 // Use r2 for index calculations and keep the hash intact in r0. 1074 // Use r2 for index calculations and keep the hash intact in r0.
1021 mov(r2, r0); 1075 mov(r2, r0);
1022 // Compute the masked index: (hash + i + i * i) & mask. 1076 // Compute the masked index: (hash + i + i * i) & mask.
1023 if (i > 0) { 1077 if (i > 0) {
1024 add(r2, Immediate(NumberDictionary::GetProbeOffset(i))); 1078 add(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i)));
1025 } 1079 }
1026 and_(r2, r1); 1080 and_(r2, r1);
1027 1081
1028 // Scale the index by multiplying by the entry size. 1082 // Scale the index by multiplying by the entry size.
1029 ASSERT(NumberDictionary::kEntrySize == 3); 1083 ASSERT(SeededNumberDictionary::kEntrySize == 3);
1030 lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 1084 lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3
1031 1085
1032 // Check if the key matches. 1086 // Check if the key matches.
1033 cmp(key, FieldOperand(elements, 1087 cmp(key, FieldOperand(elements,
1034 r2, 1088 r2,
1035 times_pointer_size, 1089 times_pointer_size,
1036 NumberDictionary::kElementsStartOffset)); 1090 SeededNumberDictionary::kElementsStartOffset));
1037 if (i != (kProbes - 1)) { 1091 if (i != (kProbes - 1)) {
1038 j(equal, &done); 1092 j(equal, &done);
1039 } else { 1093 } else {
1040 j(not_equal, miss); 1094 j(not_equal, miss);
1041 } 1095 }
1042 } 1096 }
1043 1097
1044 bind(&done); 1098 bind(&done);
1045 // Check that the value is a normal propety. 1099 // Check that the value is a normal propety.
1046 const int kDetailsOffset = 1100 const int kDetailsOffset =
1047 NumberDictionary::kElementsStartOffset + 2 * kPointerSize; 1101 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
1048 ASSERT_EQ(NORMAL, 0); 1102 ASSERT_EQ(NORMAL, 0);
1049 test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 1103 test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
1050 Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); 1104 Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize));
1051 j(not_zero, miss); 1105 j(not_zero, miss);
1052 1106
1053 // Get the value at the masked, scaled index. 1107 // Get the value at the masked, scaled index.
1054 const int kValueOffset = 1108 const int kValueOffset =
1055 NumberDictionary::kElementsStartOffset + kPointerSize; 1109 SeededNumberDictionary::kElementsStartOffset + kPointerSize;
1056 mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 1110 mov(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
1057 } 1111 }
1058 1112
1059 1113
1060 void MacroAssembler::LoadAllocationTopHelper(Register result, 1114 void MacroAssembler::LoadAllocationTopHelper(Register result,
1061 Register scratch, 1115 Register scratch,
1062 AllocationFlags flags) { 1116 AllocationFlags flags) {
1063 ExternalReference new_space_allocation_top = 1117 ExternalReference new_space_allocation_top =
1064 ExternalReference::new_space_allocation_top_address(isolate()); 1118 ExternalReference::new_space_allocation_top_address(isolate());
1065 1119
(...skipping 1619 matching lines...) Expand 10 before | Expand all | Expand 10 after
2685 cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset)); 2739 cmp(length, Operand(bitmap_scratch, MemoryChunk::kSizeOffset));
2686 Check(less_equal, "Live Bytes Count overflow chunk size"); 2740 Check(less_equal, "Live Bytes Count overflow chunk size");
2687 } 2741 }
2688 2742
2689 bind(&done); 2743 bind(&done);
2690 } 2744 }
2691 2745
2692 } } // namespace v8::internal 2746 } } // namespace v8::internal
2693 2747
2694 #endif // V8_TARGET_ARCH_IA32 2748 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698