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

Side by Side Diff: src/x64/macro-assembler-x64.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/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.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 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 488
489 489
490 void MacroAssembler::Abort(const char* msg) { 490 void MacroAssembler::Abort(const char* msg) {
491 // We want to pass the msg string like a smi to avoid GC 491 // We want to pass the msg string like a smi to avoid GC
492 // problems, however msg is not guaranteed to be aligned 492 // problems, however msg is not guaranteed to be aligned
493 // properly. Instead, we pass an aligned pointer that is 493 // properly. Instead, we pass an aligned pointer that is
494 // a proper v8 smi, but also pass the alignment difference 494 // a proper v8 smi, but also pass the alignment difference
495 // from the real pointer as a smi. 495 // from the real pointer as a smi.
496 intptr_t p1 = reinterpret_cast<intptr_t>(msg); 496 intptr_t p1 = reinterpret_cast<intptr_t>(msg);
497 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag; 497 intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag;
498 // Note: p0 might not be a valid Smi *value*, but it has a valid Smi tag. 498 // Note: p0 might not be a valid Smi _value_, but it has a valid Smi tag.
499 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi()); 499 ASSERT(reinterpret_cast<Object*>(p0)->IsSmi());
500 #ifdef DEBUG 500 #ifdef DEBUG
501 if (msg != NULL) { 501 if (msg != NULL) {
502 RecordComment("Abort message: "); 502 RecordComment("Abort message: ");
503 RecordComment(msg); 503 RecordComment(msg);
504 } 504 }
505 #endif 505 #endif
506 push(rax); 506 push(rax);
507 movq(kScratchRegister, p0, RelocInfo::NONE); 507 movq(kScratchRegister, p0, RelocInfo::NONE);
508 push(kScratchRegister); 508 push(kScratchRegister);
(...skipping 2223 matching lines...) Expand 10 before | Expand all | Expand 10 after
2732 // Value is a smi. convert to a double and store. 2732 // Value is a smi. convert to a double and store.
2733 // Preserve original value. 2733 // Preserve original value.
2734 SmiToInteger32(kScratchRegister, maybe_number); 2734 SmiToInteger32(kScratchRegister, maybe_number);
2735 cvtlsi2sd(xmm_scratch, kScratchRegister); 2735 cvtlsi2sd(xmm_scratch, kScratchRegister);
2736 movsd(FieldOperand(elements, index, times_8, FixedDoubleArray::kHeaderSize), 2736 movsd(FieldOperand(elements, index, times_8, FixedDoubleArray::kHeaderSize),
2737 xmm_scratch); 2737 xmm_scratch);
2738 bind(&done); 2738 bind(&done);
2739 } 2739 }
2740 2740
2741 2741
2742 void MacroAssembler::CompareMap(Register obj,
2743 Handle<Map> map,
2744 Label* early_success,
2745 CompareMapMode mode) {
2746 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
2747 if (mode == ALLOW_ELEMENT_TRANSITION_MAPS) {
2748 Map* transitioned_fast_element_map(
2749 map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL));
2750 ASSERT(transitioned_fast_element_map == NULL ||
2751 map->elements_kind() != FAST_ELEMENTS);
2752 if (transitioned_fast_element_map != NULL) {
2753 j(equal, early_success, Label::kNear);
2754 Cmp(FieldOperand(obj, HeapObject::kMapOffset),
2755 Handle<Map>(transitioned_fast_element_map));
2756 }
2757
2758 Map* transitioned_double_map(
2759 map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL));
2760 ASSERT(transitioned_double_map == NULL ||
2761 map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
2762 if (transitioned_double_map != NULL) {
2763 j(equal, early_success, Label::kNear);
2764 Cmp(FieldOperand(obj, HeapObject::kMapOffset),
2765 Handle<Map>(transitioned_double_map));
2766 }
2767 }
2768 }
2769
2770
2742 void MacroAssembler::CheckMap(Register obj, 2771 void MacroAssembler::CheckMap(Register obj,
2743 Handle<Map> map, 2772 Handle<Map> map,
2744 Label* fail, 2773 Label* fail,
2745 SmiCheckType smi_check_type) { 2774 SmiCheckType smi_check_type,
2775 CompareMapMode mode) {
2746 if (smi_check_type == DO_SMI_CHECK) { 2776 if (smi_check_type == DO_SMI_CHECK) {
2747 JumpIfSmi(obj, fail); 2777 JumpIfSmi(obj, fail);
2748 } 2778 }
2749 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 2779
2780 Label success;
2781 CompareMap(obj, map, &success, mode);
2750 j(not_equal, fail); 2782 j(not_equal, fail);
2783 bind(&success);
2751 } 2784 }
2752 2785
2753 2786
2754 void MacroAssembler::ClampUint8(Register reg) { 2787 void MacroAssembler::ClampUint8(Register reg) {
2755 Label done; 2788 Label done;
2756 testl(reg, Immediate(0xFFFFFF00)); 2789 testl(reg, Immediate(0xFFFFFF00));
2757 j(zero, &done, Label::kNear); 2790 j(zero, &done, Label::kNear);
2758 setcc(negative, reg); // 1 if negative, 0 if positive. 2791 setcc(negative, reg); // 1 if negative, 0 if positive.
2759 decb(reg); // 0 if negative, 255 if positive. 2792 decb(reg); // 0 if negative, 255 if positive.
2760 bind(&done); 2793 bind(&done);
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
3191 Move(kScratchRegister, Smi::FromInt(type)); 3224 Move(kScratchRegister, Smi::FromInt(type));
3192 cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); 3225 cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister);
3193 Check(equal, "stack frame types must match"); 3226 Check(equal, "stack frame types must match");
3194 } 3227 }
3195 movq(rsp, rbp); 3228 movq(rsp, rbp);
3196 pop(rbp); 3229 pop(rbp);
3197 } 3230 }
3198 3231
3199 3232
3200 void MacroAssembler::EnterExitFramePrologue(bool save_rax) { 3233 void MacroAssembler::EnterExitFramePrologue(bool save_rax) {
3201 // Setup the frame structure on the stack. 3234 // Set up the frame structure on the stack.
3202 // All constants are relative to the frame pointer of the exit frame. 3235 // All constants are relative to the frame pointer of the exit frame.
3203 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); 3236 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize);
3204 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); 3237 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize);
3205 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 3238 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize);
3206 push(rbp); 3239 push(rbp);
3207 movq(rbp, rsp); 3240 movq(rbp, rsp);
3208 3241
3209 // Reserve room for entry stack pointer and push the code object. 3242 // Reserve room for entry stack pointer and push the code object.
3210 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 3243 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
3211 push(Immediate(0)); // Saved entry sp, patched before call. 3244 push(Immediate(0)); // Saved entry sp, patched before call.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3251 } 3284 }
3252 3285
3253 // Patch the saved entry sp. 3286 // Patch the saved entry sp.
3254 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); 3287 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
3255 } 3288 }
3256 3289
3257 3290
3258 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { 3291 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) {
3259 EnterExitFramePrologue(true); 3292 EnterExitFramePrologue(true);
3260 3293
3261 // Setup argv in callee-saved register r15. It is reused in LeaveExitFrame, 3294 // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame,
3262 // so it must be retained across the C-call. 3295 // so it must be retained across the C-call.
3263 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 3296 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
3264 lea(r15, Operand(rbp, r14, times_pointer_size, offset)); 3297 lea(r15, Operand(rbp, r14, times_pointer_size, offset));
3265 3298
3266 EnterExitFrameEpilogue(arg_stack_space, save_doubles); 3299 EnterExitFrameEpilogue(arg_stack_space, save_doubles);
3267 } 3300 }
3268 3301
3269 3302
3270 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) { 3303 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) {
3271 EnterExitFramePrologue(false); 3304 EnterExitFramePrologue(false);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
3379 int token_offset = 3412 int token_offset =
3380 Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize; 3413 Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize;
3381 movq(scratch, FieldOperand(scratch, token_offset)); 3414 movq(scratch, FieldOperand(scratch, token_offset));
3382 cmpq(scratch, FieldOperand(kScratchRegister, token_offset)); 3415 cmpq(scratch, FieldOperand(kScratchRegister, token_offset));
3383 j(not_equal, miss); 3416 j(not_equal, miss);
3384 3417
3385 bind(&same_contexts); 3418 bind(&same_contexts);
3386 } 3419 }
3387 3420
3388 3421
3422 void MacroAssembler::GetNumberHash(Register r0, Register scratch) {
3423 // First of all we assign the hash seed to scratch.
3424 LoadRoot(scratch, Heap::kHashSeedRootIndex);
3425 SmiToInteger32(scratch, scratch);
3426
3427 // Xor original key with a seed.
3428 xorl(r0, scratch);
3429
3430 // Compute the hash code from the untagged key. This must be kept in sync
3431 // with ComputeIntegerHash in utils.h.
3432 //
3433 // hash = ~hash + (hash << 15);
3434 movl(scratch, r0);
3435 notl(r0);
3436 shll(scratch, Immediate(15));
3437 addl(r0, scratch);
3438 // hash = hash ^ (hash >> 12);
3439 movl(scratch, r0);
3440 shrl(scratch, Immediate(12));
3441 xorl(r0, scratch);
3442 // hash = hash + (hash << 2);
3443 leal(r0, Operand(r0, r0, times_4, 0));
3444 // hash = hash ^ (hash >> 4);
3445 movl(scratch, r0);
3446 shrl(scratch, Immediate(4));
3447 xorl(r0, scratch);
3448 // hash = hash * 2057;
3449 imull(r0, r0, Immediate(2057));
3450 // hash = hash ^ (hash >> 16);
3451 movl(scratch, r0);
3452 shrl(scratch, Immediate(16));
3453 xorl(r0, scratch);
3454 }
3455
3456
3457
3389 void MacroAssembler::LoadFromNumberDictionary(Label* miss, 3458 void MacroAssembler::LoadFromNumberDictionary(Label* miss,
3390 Register elements, 3459 Register elements,
3391 Register key, 3460 Register key,
3392 Register r0, 3461 Register r0,
3393 Register r1, 3462 Register r1,
3394 Register r2, 3463 Register r2,
3395 Register result) { 3464 Register result) {
3396 // Register use: 3465 // Register use:
3397 // 3466 //
3398 // elements - holds the slow-case elements of the receiver on entry. 3467 // elements - holds the slow-case elements of the receiver on entry.
(...skipping 10 matching lines...) Expand all
3409 // 3478 //
3410 // r2 - used for the index into the dictionary. 3479 // r2 - used for the index into the dictionary.
3411 // 3480 //
3412 // result - holds the result on exit if the load succeeded. 3481 // result - holds the result on exit if the load succeeded.
3413 // Allowed to be the same as 'key' or 'result'. 3482 // Allowed to be the same as 'key' or 'result'.
3414 // Unchanged on bailout so 'key' or 'result' can be used 3483 // Unchanged on bailout so 'key' or 'result' can be used
3415 // in further computation. 3484 // in further computation.
3416 3485
3417 Label done; 3486 Label done;
3418 3487
3419 // Compute the hash code from the untagged key. This must be kept in sync 3488 GetNumberHash(r0, r1);
3420 // with ComputeIntegerHash in utils.h.
3421 //
3422 // hash = ~hash + (hash << 15);
3423 movl(r1, r0);
3424 notl(r0);
3425 shll(r1, Immediate(15));
3426 addl(r0, r1);
3427 // hash = hash ^ (hash >> 12);
3428 movl(r1, r0);
3429 shrl(r1, Immediate(12));
3430 xorl(r0, r1);
3431 // hash = hash + (hash << 2);
3432 leal(r0, Operand(r0, r0, times_4, 0));
3433 // hash = hash ^ (hash >> 4);
3434 movl(r1, r0);
3435 shrl(r1, Immediate(4));
3436 xorl(r0, r1);
3437 // hash = hash * 2057;
3438 imull(r0, r0, Immediate(2057));
3439 // hash = hash ^ (hash >> 16);
3440 movl(r1, r0);
3441 shrl(r1, Immediate(16));
3442 xorl(r0, r1);
3443 3489
3444 // Compute capacity mask. 3490 // Compute capacity mask.
3445 SmiToInteger32(r1, 3491 SmiToInteger32(r1, FieldOperand(elements,
3446 FieldOperand(elements, NumberDictionary::kCapacityOffset)); 3492 SeededNumberDictionary::kCapacityOffset));
3447 decl(r1); 3493 decl(r1);
3448 3494
3449 // Generate an unrolled loop that performs a few probes before giving up. 3495 // Generate an unrolled loop that performs a few probes before giving up.
3450 const int kProbes = 4; 3496 const int kProbes = 4;
3451 for (int i = 0; i < kProbes; i++) { 3497 for (int i = 0; i < kProbes; i++) {
3452 // Use r2 for index calculations and keep the hash intact in r0. 3498 // Use r2 for index calculations and keep the hash intact in r0.
3453 movq(r2, r0); 3499 movq(r2, r0);
3454 // Compute the masked index: (hash + i + i * i) & mask. 3500 // Compute the masked index: (hash + i + i * i) & mask.
3455 if (i > 0) { 3501 if (i > 0) {
3456 addl(r2, Immediate(NumberDictionary::GetProbeOffset(i))); 3502 addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i)));
3457 } 3503 }
3458 and_(r2, r1); 3504 and_(r2, r1);
3459 3505
3460 // Scale the index by multiplying by the entry size. 3506 // Scale the index by multiplying by the entry size.
3461 ASSERT(NumberDictionary::kEntrySize == 3); 3507 ASSERT(SeededNumberDictionary::kEntrySize == 3);
3462 lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 3508 lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3
3463 3509
3464 // Check if the key matches. 3510 // Check if the key matches.
3465 cmpq(key, FieldOperand(elements, 3511 cmpq(key, FieldOperand(elements,
3466 r2, 3512 r2,
3467 times_pointer_size, 3513 times_pointer_size,
3468 NumberDictionary::kElementsStartOffset)); 3514 SeededNumberDictionary::kElementsStartOffset));
3469 if (i != (kProbes - 1)) { 3515 if (i != (kProbes - 1)) {
3470 j(equal, &done); 3516 j(equal, &done);
3471 } else { 3517 } else {
3472 j(not_equal, miss); 3518 j(not_equal, miss);
3473 } 3519 }
3474 } 3520 }
3475 3521
3476 bind(&done); 3522 bind(&done);
3477 // Check that the value is a normal propety. 3523 // Check that the value is a normal propety.
3478 const int kDetailsOffset = 3524 const int kDetailsOffset =
3479 NumberDictionary::kElementsStartOffset + 2 * kPointerSize; 3525 SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
3480 ASSERT_EQ(NORMAL, 0); 3526 ASSERT_EQ(NORMAL, 0);
3481 Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 3527 Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
3482 Smi::FromInt(PropertyDetails::TypeField::kMask)); 3528 Smi::FromInt(PropertyDetails::TypeField::kMask));
3483 j(not_zero, miss); 3529 j(not_zero, miss);
3484 3530
3485 // Get the value at the masked, scaled index. 3531 // Get the value at the masked, scaled index.
3486 const int kValueOffset = 3532 const int kValueOffset =
3487 NumberDictionary::kElementsStartOffset + kPointerSize; 3533 SeededNumberDictionary::kElementsStartOffset + kPointerSize;
3488 movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 3534 movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
3489 } 3535 }
3490 3536
3491 3537
3492 void MacroAssembler::LoadAllocationTopHelper(Register result, 3538 void MacroAssembler::LoadAllocationTopHelper(Register result,
3493 Register scratch, 3539 Register scratch,
3494 AllocationFlags flags) { 3540 AllocationFlags flags) {
3495 ExternalReference new_space_allocation_top = 3541 ExternalReference new_space_allocation_top =
3496 ExternalReference::new_space_allocation_top_address(isolate()); 3542 ExternalReference::new_space_allocation_top_address(isolate());
3497 3543
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after
4279 4325
4280 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); 4326 and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask));
4281 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); 4327 addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length);
4282 4328
4283 bind(&done); 4329 bind(&done);
4284 } 4330 }
4285 4331
4286 } } // namespace v8::internal 4332 } } // namespace v8::internal
4287 4333
4288 #endif // V8_TARGET_ARCH_X64 4334 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698