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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 10170030: Implement tracking and optimizations of packed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Platforms ports and review feedback Created 8 years, 7 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
OLDNEW
1 // Copyright 2012 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
(...skipping 2306 matching lines...) Expand 10 before | Expand all | Expand 10 after
2317 __ j(equal, &done, Label::kNear); 2317 __ j(equal, &done, Label::kNear);
2318 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset), 2318 __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
2319 Heap::kFixedCOWArrayMapRootIndex); 2319 Heap::kFixedCOWArrayMapRootIndex);
2320 __ j(equal, &done, Label::kNear); 2320 __ j(equal, &done, Label::kNear);
2321 Register temp((result.is(rax)) ? rbx : rax); 2321 Register temp((result.is(rax)) ? rbx : rax);
2322 __ push(temp); 2322 __ push(temp);
2323 __ movq(temp, FieldOperand(result, HeapObject::kMapOffset)); 2323 __ movq(temp, FieldOperand(result, HeapObject::kMapOffset));
2324 __ movzxbq(temp, FieldOperand(temp, Map::kBitField2Offset)); 2324 __ movzxbq(temp, FieldOperand(temp, Map::kBitField2Offset));
2325 __ and_(temp, Immediate(Map::kElementsKindMask)); 2325 __ and_(temp, Immediate(Map::kElementsKindMask));
2326 __ shr(temp, Immediate(Map::kElementsKindShift)); 2326 __ shr(temp, Immediate(Map::kElementsKindShift));
2327 __ cmpl(temp, Immediate(FAST_ELEMENTS)); 2327 __ cmpl(temp, Immediate(GetInitialFastElementsKind()));
2328 __ j(equal, &ok, Label::kNear); 2328 __ j(less, &fail, Label::kNear);
2329 __ cmpl(temp, Immediate(TERMINAL_FAST_ELEMENTS_KIND));
2330 __ j(less_equal, &ok, Label::kNear);
2329 __ cmpl(temp, Immediate(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); 2331 __ cmpl(temp, Immediate(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND));
2330 __ j(less, &fail, Label::kNear); 2332 __ j(less, &fail, Label::kNear);
2331 __ cmpl(temp, Immediate(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); 2333 __ cmpl(temp, Immediate(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND));
2332 __ j(less_equal, &ok, Label::kNear); 2334 __ j(less_equal, &ok, Label::kNear);
2333 __ bind(&fail); 2335 __ bind(&fail);
2334 __ Abort("Check for fast or external elements failed"); 2336 __ Abort("Check for fast or external elements failed");
2335 __ bind(&ok); 2337 __ bind(&ok);
2336 __ pop(temp); 2338 __ pop(temp);
2337 __ bind(&done); 2339 __ bind(&done);
2338 } 2340 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2380 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 2382 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
2381 DeoptimizeIf(equal, instr->environment()); 2383 DeoptimizeIf(equal, instr->environment());
2382 } 2384 }
2383 } 2385 }
2384 2386
2385 2387
2386 void LCodeGen::DoLoadKeyedFastDoubleElement( 2388 void LCodeGen::DoLoadKeyedFastDoubleElement(
2387 LLoadKeyedFastDoubleElement* instr) { 2389 LLoadKeyedFastDoubleElement* instr) {
2388 XMMRegister result(ToDoubleRegister(instr->result())); 2390 XMMRegister result(ToDoubleRegister(instr->result()));
2389 2391
2390 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + 2392 if (instr->hydrogen()->RequiresHoleCheck()) {
2391 sizeof(kHoleNanLower32); 2393 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2392 Operand hole_check_operand = BuildFastArrayOperand( 2394 sizeof(kHoleNanLower32);
2393 instr->elements(), 2395 Operand hole_check_operand = BuildFastArrayOperand(
2394 instr->key(), 2396 instr->elements(),
2395 FAST_DOUBLE_ELEMENTS, 2397 instr->key(),
2396 offset); 2398 FAST_DOUBLE_ELEMENTS,
2397 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); 2399 offset);
2398 DeoptimizeIf(equal, instr->environment()); 2400 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
2401 DeoptimizeIf(equal, instr->environment());
2402 }
2399 2403
2400 Operand double_load_operand = BuildFastArrayOperand( 2404 Operand double_load_operand = BuildFastArrayOperand(
2401 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, 2405 instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
2402 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 2406 FixedDoubleArray::kHeaderSize - kHeapObjectTag);
2403 __ movsd(result, double_load_operand); 2407 __ movsd(result, double_load_operand);
2404 } 2408 }
2405 2409
2406 2410
2407 Operand LCodeGen::BuildFastArrayOperand( 2411 Operand LCodeGen::BuildFastArrayOperand(
2408 LOperand* elements_pointer, 2412 LOperand* elements_pointer,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2460 __ movl(result, operand); 2464 __ movl(result, operand);
2461 __ testl(result, result); 2465 __ testl(result, result);
2462 // TODO(danno): we could be more clever here, perhaps having a special 2466 // TODO(danno): we could be more clever here, perhaps having a special
2463 // version of the stub that detects if the overflow case actually 2467 // version of the stub that detects if the overflow case actually
2464 // happens, and generate code that returns a double rather than int. 2468 // happens, and generate code that returns a double rather than int.
2465 DeoptimizeIf(negative, instr->environment()); 2469 DeoptimizeIf(negative, instr->environment());
2466 break; 2470 break;
2467 case EXTERNAL_FLOAT_ELEMENTS: 2471 case EXTERNAL_FLOAT_ELEMENTS:
2468 case EXTERNAL_DOUBLE_ELEMENTS: 2472 case EXTERNAL_DOUBLE_ELEMENTS:
2469 case FAST_ELEMENTS: 2473 case FAST_ELEMENTS:
2470 case FAST_SMI_ONLY_ELEMENTS: 2474 case FAST_SMI_ELEMENTS:
2471 case FAST_DOUBLE_ELEMENTS: 2475 case FAST_DOUBLE_ELEMENTS:
2476 case FAST_HOLEY_ELEMENTS:
2477 case FAST_HOLEY_SMI_ELEMENTS:
2478 case FAST_HOLEY_DOUBLE_ELEMENTS:
2472 case DICTIONARY_ELEMENTS: 2479 case DICTIONARY_ELEMENTS:
2473 case NON_STRICT_ARGUMENTS_ELEMENTS: 2480 case NON_STRICT_ARGUMENTS_ELEMENTS:
2474 UNREACHABLE(); 2481 UNREACHABLE();
2475 break; 2482 break;
2476 } 2483 }
2477 } 2484 }
2478 } 2485 }
2479 2486
2480 2487
2481 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2488 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after
3351 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3358 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3352 __ movw(operand, value); 3359 __ movw(operand, value);
3353 break; 3360 break;
3354 case EXTERNAL_INT_ELEMENTS: 3361 case EXTERNAL_INT_ELEMENTS:
3355 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3362 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3356 __ movl(operand, value); 3363 __ movl(operand, value);
3357 break; 3364 break;
3358 case EXTERNAL_FLOAT_ELEMENTS: 3365 case EXTERNAL_FLOAT_ELEMENTS:
3359 case EXTERNAL_DOUBLE_ELEMENTS: 3366 case EXTERNAL_DOUBLE_ELEMENTS:
3360 case FAST_ELEMENTS: 3367 case FAST_ELEMENTS:
3361 case FAST_SMI_ONLY_ELEMENTS: 3368 case FAST_SMI_ELEMENTS:
3362 case FAST_DOUBLE_ELEMENTS: 3369 case FAST_DOUBLE_ELEMENTS:
3370 case FAST_HOLEY_ELEMENTS:
3371 case FAST_HOLEY_SMI_ELEMENTS:
3372 case FAST_HOLEY_DOUBLE_ELEMENTS:
3363 case DICTIONARY_ELEMENTS: 3373 case DICTIONARY_ELEMENTS:
3364 case NON_STRICT_ARGUMENTS_ELEMENTS: 3374 case NON_STRICT_ARGUMENTS_ELEMENTS:
3365 UNREACHABLE(); 3375 UNREACHABLE();
3366 break; 3376 break;
3367 } 3377 }
3368 } 3378 }
3369 } 3379 }
3370 3380
3371 3381
3372 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 3382 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3477 3487
3478 Handle<Map> from_map = instr->original_map(); 3488 Handle<Map> from_map = instr->original_map();
3479 Handle<Map> to_map = instr->transitioned_map(); 3489 Handle<Map> to_map = instr->transitioned_map();
3480 ElementsKind from_kind = from_map->elements_kind(); 3490 ElementsKind from_kind = from_map->elements_kind();
3481 ElementsKind to_kind = to_map->elements_kind(); 3491 ElementsKind to_kind = to_map->elements_kind();
3482 3492
3483 Label not_applicable; 3493 Label not_applicable;
3484 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); 3494 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map);
3485 __ j(not_equal, &not_applicable); 3495 __ j(not_equal, &not_applicable);
3486 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT); 3496 __ movq(new_map_reg, to_map, RelocInfo::EMBEDDED_OBJECT);
3487 if (from_kind == FAST_SMI_ONLY_ELEMENTS && to_kind == FAST_ELEMENTS) { 3497 bool simple_map_change = (GetHoleyElementsKind(from_kind) == to_kind) ||
3498 (IsFastSmiElementsKind(from_kind) &&
3499 IsFastObjectElementsKind(to_kind));
3500 if (simple_map_change) {
3488 __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg); 3501 __ movq(FieldOperand(object_reg, HeapObject::kMapOffset), new_map_reg);
3489 // Write barrier. 3502 // Write barrier.
3490 ASSERT_NE(instr->temp_reg(), NULL); 3503 ASSERT_NE(instr->temp_reg(), NULL);
3491 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg, 3504 __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
3492 ToRegister(instr->temp_reg()), kDontSaveFPRegs); 3505 ToRegister(instr->temp_reg()), kDontSaveFPRegs);
3493 } else if (from_kind == FAST_SMI_ONLY_ELEMENTS && 3506 } else if (IsFastSmiElementsKind(from_kind) &&
3494 to_kind == FAST_DOUBLE_ELEMENTS) { 3507 IsFastDoubleElementsKind(to_kind)) {
3495 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3508 Register fixed_object_reg = ToRegister(instr->temp_reg());
3496 ASSERT(fixed_object_reg.is(rdx)); 3509 ASSERT(fixed_object_reg.is(rdx));
3497 ASSERT(new_map_reg.is(rbx)); 3510 ASSERT(new_map_reg.is(rbx));
3498 __ movq(fixed_object_reg, object_reg); 3511 __ movq(fixed_object_reg, object_reg);
3499 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(), 3512 CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
3500 RelocInfo::CODE_TARGET, instr); 3513 RelocInfo::CODE_TARGET, instr);
3501 } else if (from_kind == FAST_DOUBLE_ELEMENTS && to_kind == FAST_ELEMENTS) { 3514 } else if (IsFastDoubleElementsKind(from_kind) &&
3515 IsFastElementsKind(to_kind)) {
Jakob Kummerow 2012/05/22 17:36:49 IsFastObjectElementsKind(to_kind) ?
danno 2012/05/23 14:25:36 Done.
3502 Register fixed_object_reg = ToRegister(instr->temp_reg()); 3516 Register fixed_object_reg = ToRegister(instr->temp_reg());
3503 ASSERT(fixed_object_reg.is(rdx)); 3517 ASSERT(fixed_object_reg.is(rdx));
3504 ASSERT(new_map_reg.is(rbx)); 3518 ASSERT(new_map_reg.is(rbx));
3505 __ movq(fixed_object_reg, object_reg); 3519 __ movq(fixed_object_reg, object_reg);
3506 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(), 3520 CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
3507 RelocInfo::CODE_TARGET, instr); 3521 RelocInfo::CODE_TARGET, instr);
3508 } else { 3522 } else {
3509 UNREACHABLE(); 3523 UNREACHABLE();
3510 } 3524 }
3511 __ bind(&not_applicable); 3525 __ bind(&not_applicable);
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
4165 } 4179 }
4166 4180
4167 4181
4168 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { 4182 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) {
4169 Heap* heap = isolate()->heap(); 4183 Heap* heap = isolate()->heap();
4170 ElementsKind boilerplate_elements_kind = 4184 ElementsKind boilerplate_elements_kind =
4171 instr->hydrogen()->boilerplate_elements_kind(); 4185 instr->hydrogen()->boilerplate_elements_kind();
4172 4186
4173 // Deopt if the array literal boilerplate ElementsKind is of a type different 4187 // Deopt if the array literal boilerplate ElementsKind is of a type different
4174 // than the expected one. The check isn't necessary if the boilerplate has 4188 // than the expected one. The check isn't necessary if the boilerplate has
4175 // already been converted to FAST_ELEMENTS. 4189 // already been converted to TERMINAL_FAST_ELEMENTS_KIND.
4176 if (boilerplate_elements_kind != FAST_ELEMENTS) { 4190 if (CanTransitionToMoreGeneralFastElementsKind(
4191 boilerplate_elements_kind, true)) {
4177 __ LoadHeapObject(rax, instr->hydrogen()->boilerplate_object()); 4192 __ LoadHeapObject(rax, instr->hydrogen()->boilerplate_object());
4178 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 4193 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
4179 // Load the map's "bit field 2". 4194 // Load the map's "bit field 2".
4180 __ movb(rbx, FieldOperand(rbx, Map::kBitField2Offset)); 4195 __ movb(rbx, FieldOperand(rbx, Map::kBitField2Offset));
4181 // Retrieve elements_kind from bit field 2. 4196 // Retrieve elements_kind from bit field 2.
4182 __ and_(rbx, Immediate(Map::kElementsKindMask)); 4197 __ and_(rbx, Immediate(Map::kElementsKindMask));
4183 __ cmpb(rbx, Immediate(boilerplate_elements_kind << 4198 __ cmpb(rbx, Immediate(boilerplate_elements_kind <<
4184 Map::kElementsKindShift)); 4199 Map::kElementsKindShift));
4185 DeoptimizeIf(not_equal, instr->environment()); 4200 DeoptimizeIf(not_equal, instr->environment());
4186 } 4201 }
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
4312 } 4327 }
4313 } 4328 }
4314 } 4329 }
4315 4330
4316 4331
4317 void LCodeGen::DoFastLiteral(LFastLiteral* instr) { 4332 void LCodeGen::DoFastLiteral(LFastLiteral* instr) {
4318 int size = instr->hydrogen()->total_size(); 4333 int size = instr->hydrogen()->total_size();
4319 ElementsKind boilerplate_elements_kind = 4334 ElementsKind boilerplate_elements_kind =
4320 instr->hydrogen()->boilerplate()->GetElementsKind(); 4335 instr->hydrogen()->boilerplate()->GetElementsKind();
4321 4336
4322 // Deopt if the literal boilerplate ElementsKind is of a type different than 4337 // Deopt if the array literal boilerplate ElementsKind is of a type different
4323 // the expected one. The check isn't necessary if the boilerplate has already 4338 // than the expected one. The check isn't necessary if the boilerplate has
4324 // been converted to FAST_ELEMENTS. 4339 // already been converted to FAST_ELEMENTS.
Jakob Kummerow 2012/05/22 17:36:49 nit: s/FAST_ELEMENTS/TERMINAL_FAST_ELEMENTS_KIND/
danno 2012/05/23 14:25:36 Done.
4325 if (boilerplate_elements_kind != FAST_ELEMENTS) { 4340 if (CanTransitionToMoreGeneralFastElementsKind(
4341 boilerplate_elements_kind, true)) {
4326 __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate()); 4342 __ LoadHeapObject(rbx, instr->hydrogen()->boilerplate());
4327 __ movq(rcx, FieldOperand(rbx, HeapObject::kMapOffset)); 4343 __ movq(rcx, FieldOperand(rbx, HeapObject::kMapOffset));
4328 // Load the map's "bit field 2". 4344 // Load the map's "bit field 2".
4329 __ movb(rcx, FieldOperand(rcx, Map::kBitField2Offset)); 4345 __ movb(rcx, FieldOperand(rcx, Map::kBitField2Offset));
4330 // Retrieve elements_kind from bit field 2. 4346 // Retrieve elements_kind from bit field 2.
4331 __ and_(rcx, Immediate(Map::kElementsKindMask)); 4347 __ and_(rcx, Immediate(Map::kElementsKindMask));
4332 __ cmpb(rcx, Immediate(boilerplate_elements_kind << 4348 __ cmpb(rcx, Immediate(boilerplate_elements_kind <<
4333 Map::kElementsKindShift)); 4349 Map::kElementsKindShift));
4334 DeoptimizeIf(not_equal, instr->environment()); 4350 DeoptimizeIf(not_equal, instr->environment());
4335 } 4351 }
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
4811 FixedArray::kHeaderSize - kPointerSize)); 4827 FixedArray::kHeaderSize - kPointerSize));
4812 __ bind(&done); 4828 __ bind(&done);
4813 } 4829 }
4814 4830
4815 4831
4816 #undef __ 4832 #undef __
4817 4833
4818 } } // namespace v8::internal 4834 } } // namespace v8::internal
4819 4835
4820 #endif // V8_TARGET_ARCH_X64 4836 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698