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

Side by Side Diff: src/ia32/ic-ia32.cc

Issue 2441002: ARM: Add more logic to the generic keyed load stub... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 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 | « src/arm/ic-arm.cc ('k') | src/v8-counters.h » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 } 298 }
299 299
300 300
301 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 301 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
302 // ----------- S t a t e ------------- 302 // ----------- S t a t e -------------
303 // -- eax : key 303 // -- eax : key
304 // -- edx : receiver 304 // -- edx : receiver
305 // -- esp[0] : return address 305 // -- esp[0] : return address
306 // ----------------------------------- 306 // -----------------------------------
307 Label slow, check_string, index_smi, index_string; 307 Label slow, check_string, index_smi, index_string;
308 Label check_pixel_array, probe_dictionary; 308 Label check_pixel_array, probe_dictionary, check_number_dictionary;
309 Label check_number_dictionary;
310 309
311 // Check that the object isn't a smi. 310 // Check that the object isn't a smi.
312 __ test(edx, Immediate(kSmiTagMask)); 311 __ test(edx, Immediate(kSmiTagMask));
313 __ j(zero, &slow, not_taken); 312 __ j(zero, &slow, not_taken);
314 313
315 // Get the map of the receiver. 314 // Get the map of the receiver.
316 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 315 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
317 316
318 // Check bit field. 317 // Check bit field.
319 __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset)); 318 __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset));
320 __ test(ebx, Immediate(kSlowCaseBitFieldMask)); 319 __ test(ebx, Immediate(kSlowCaseBitFieldMask));
321 __ j(not_zero, &slow, not_taken); 320 __ j(not_zero, &slow, not_taken);
322 // Check that the object is some kind of JS object EXCEPT JS Value type. 321 // Check that the object is some kind of JS object EXCEPT JS Value type.
323 // In the case that the object is a value-wrapper object, 322 // In the case that the object is a value-wrapper object,
324 // we enter the runtime system to make sure that indexing 323 // we enter the runtime system to make sure that indexing
325 // into string objects work as intended. 324 // into string objects work as intended.
326 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); 325 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
327 __ CmpInstanceType(ecx, JS_OBJECT_TYPE); 326 __ CmpInstanceType(ecx, JS_OBJECT_TYPE);
328 __ j(below, &slow, not_taken); 327 __ j(below, &slow, not_taken);
329 // Check that the key is a smi. 328 // Check that the key is a smi.
330 __ test(eax, Immediate(kSmiTagMask)); 329 __ test(eax, Immediate(kSmiTagMask));
331 __ j(not_zero, &check_string, not_taken); 330 __ j(not_zero, &check_string, not_taken);
332 // Get the elements array of the object.
333 __ bind(&index_smi); 331 __ bind(&index_smi);
332 // Now the key is known to be a smi. This place is also jumped to from below
333 // where a numeric string is converted to a smi.
334 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 334 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
335 // Check that the object is in fast mode (not dictionary). 335 // Check that the object is in fast mode (not dictionary).
336 __ CheckMap(ecx, Factory::fixed_array_map(), &check_pixel_array, true); 336 __ CheckMap(ecx, Factory::fixed_array_map(), &check_pixel_array, true);
337 // Check that the key (index) is within bounds. 337 // Check that the key (index) is within bounds.
338 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset)); 338 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
339 __ j(above_equal, &slow); 339 __ j(above_equal, &slow);
340 // Fast case: Do the load. 340 // Fast case: Do the load.
341 ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0)); 341 ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0));
342 __ mov(ecx, FieldOperand(ecx, eax, times_2, FixedArray::kHeaderSize)); 342 __ mov(ecx, FieldOperand(ecx, eax, times_2, FixedArray::kHeaderSize));
343 __ cmp(Operand(ecx), Immediate(Factory::the_hole_value())); 343 __ cmp(Operand(ecx), Immediate(Factory::the_hole_value()));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 // edx: receiver 402 // edx: receiver
403 // eax: key 403 // eax: key
404 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx); 404 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ecx);
405 __ j(above_equal, &slow); 405 __ j(above_equal, &slow);
406 // Is the string an array index, with cached numeric value? 406 // Is the string an array index, with cached numeric value?
407 __ mov(ebx, FieldOperand(eax, String::kHashFieldOffset)); 407 __ mov(ebx, FieldOperand(eax, String::kHashFieldOffset));
408 __ test(ebx, Immediate(String::kIsArrayIndexMask)); 408 __ test(ebx, Immediate(String::kIsArrayIndexMask));
409 __ j(not_zero, &index_string, not_taken); 409 __ j(not_zero, &index_string, not_taken);
410 410
411 // Is the string a symbol? 411 // Is the string a symbol?
412 // ecx: key map.
412 __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 413 __ movzx_b(ebx, FieldOperand(ecx, Map::kInstanceTypeOffset));
413 ASSERT(kSymbolTag != 0); 414 ASSERT(kSymbolTag != 0);
414 __ test(ebx, Immediate(kIsSymbolMask)); 415 __ test(ebx, Immediate(kIsSymbolMask));
415 __ j(zero, &slow, not_taken); 416 __ j(zero, &slow, not_taken);
416 417
417 // If the receiver is a fast-case object, check the keyed lookup 418 // If the receiver is a fast-case object, check the keyed lookup
418 // cache. Otherwise probe the dictionary. 419 // cache. Otherwise probe the dictionary.
419 __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset)); 420 __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset));
420 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 421 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
421 Immediate(Factory::hash_table_map())); 422 Immediate(Factory::hash_table_map()));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets)); 455 Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets));
455 __ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset)); 456 __ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
456 __ cmp(edi, Operand(ecx)); 457 __ cmp(edi, Operand(ecx));
457 __ j(above_equal, &slow); 458 __ j(above_equal, &slow);
458 459
459 // Load in-object property. 460 // Load in-object property.
460 __ sub(edi, Operand(ecx)); 461 __ sub(edi, Operand(ecx));
461 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset)); 462 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
462 __ add(ecx, Operand(edi)); 463 __ add(ecx, Operand(edi));
463 __ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0)); 464 __ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0));
465 __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1);
464 __ ret(0); 466 __ ret(0);
465 467
466 // Do a quick inline probe of the receiver's dictionary, if it 468 // Do a quick inline probe of the receiver's dictionary, if it
467 // exists. 469 // exists.
468 __ bind(&probe_dictionary); 470 __ bind(&probe_dictionary);
469 GenerateDictionaryLoad(masm, 471 GenerateDictionaryLoad(masm,
470 &slow, 472 &slow,
471 edx, 473 edx,
472 eax, 474 eax,
473 ebx, 475 ebx,
474 ecx, 476 ecx,
475 edi, 477 edi,
476 DICTIONARY_CHECK_DONE); 478 DICTIONARY_CHECK_DONE);
477 __ mov(eax, ecx); 479 __ mov(eax, ecx);
478 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); 480 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
479 __ ret(0); 481 __ ret(0);
480 482
481 // If the hash field contains an array index pick it out. The assert checks 483 // If the hash field contains an array index pick it out. The assert checks
482 // that the constants for the maximum number of digits for an array index 484 // that the constants for the maximum number of digits for an array index
483 // cached in the hash field and the number of bits reserved for it does not 485 // cached in the hash field and the number of bits reserved for it does not
484 // conflict. 486 // conflict.
485 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 487 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
486 (1 << String::kArrayIndexValueBits)); 488 (1 << String::kArrayIndexValueBits));
487 __ bind(&index_string); 489 __ bind(&index_string);
488 // We want the smi-tagged index in eax. kArrayIndexValueMask has zeros in 490 // We want the smi-tagged index in eax. kArrayIndexValueMask has zeros in
489 // the low kHashShift bits. 491 // the low kHashShift bits.
492 // eax: key (string).
493 // ebx: hash field.
494 // edx: receiver.
490 ASSERT(String::kHashShift >= kSmiTagSize); 495 ASSERT(String::kHashShift >= kSmiTagSize);
491 __ and_(ebx, String::kArrayIndexValueMask); 496 __ and_(ebx, String::kArrayIndexValueMask);
492 __ shr(ebx, String::kHashShift - kSmiTagSize); 497 __ shr(ebx, String::kHashShift - kSmiTagSize);
498 // Here we actually clobber the key (eax) which will be used if calling into
499 // runtime later. However as the new key is the numeric value of a string key
500 // there is no difference in using either key.
493 __ mov(eax, ebx); 501 __ mov(eax, ebx);
502 // Now jump to the place where smi keys are handled.
494 __ jmp(&index_smi); 503 __ jmp(&index_smi);
495 } 504 }
496 505
497 506
498 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { 507 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
499 // ----------- S t a t e ------------- 508 // ----------- S t a t e -------------
500 // -- eax : key (index) 509 // -- eax : key (index)
501 // -- edx : receiver 510 // -- edx : receiver
502 // -- esp[0] : return address 511 // -- esp[0] : return address
503 // ----------------------------------- 512 // -----------------------------------
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1609 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss)); 1618 ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss));
1610 __ TailCallExternalReference(ref, 3, 1); 1619 __ TailCallExternalReference(ref, 3, 1);
1611 } 1620 }
1612 1621
1613 #undef __ 1622 #undef __
1614 1623
1615 1624
1616 } } // namespace v8::internal 1625 } } // namespace v8::internal
1617 1626
1618 #endif // V8_TARGET_ARCH_IA32 1627 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm/ic-arm.cc ('k') | src/v8-counters.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698