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

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

Issue 11272: When probing a dictionary backing storage in generated code, make sure... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 years, 1 month 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/ic-arm.cc ('k') | test/cctest/test-api.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 23 matching lines...) Expand all
34 34
35 namespace v8 { namespace internal { 35 namespace v8 { namespace internal {
36 36
37 // ---------------------------------------------------------------------------- 37 // ----------------------------------------------------------------------------
38 // Static IC stub generators. 38 // Static IC stub generators.
39 // 39 //
40 40
41 #define __ masm-> 41 #define __ masm->
42 42
43 43
44 // Helper function used from LoadIC/CallIC GenerateNormal. 44 // Helper function used to load a property from a dictionary backing storage.
45 static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label, 45 static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label,
46 Register r0, Register r1, Register r2, 46 Register r0, Register r1, Register r2,
47 Register name) { 47 Register name) {
48 // Register use: 48 // Register use:
49 // 49 //
50 // r0 - used to hold the property dictionary. 50 // r0 - used to hold the property dictionary.
51 // 51 //
52 // r1 - initially the receiver 52 // r1 - initially the receiver
53 // - used for the index into the property dictionary 53 // - used for the index into the property dictionary
54 // - holds the result on exit. 54 // - holds the result on exit.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 __ test(Operand(r0, r1, times_4, kDetailsOffset - kHeapObjectTag), 114 __ test(Operand(r0, r1, times_4, kDetailsOffset - kHeapObjectTag),
115 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); 115 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize));
116 __ j(not_zero, miss_label, not_taken); 116 __ j(not_zero, miss_label, not_taken);
117 117
118 // Get the value at the masked, scaled index. 118 // Get the value at the masked, scaled index.
119 const int kValueOffset = kElementsStartOffset + kPointerSize; 119 const int kValueOffset = kElementsStartOffset + kPointerSize;
120 __ mov(r1, Operand(r0, r1, times_4, kValueOffset - kHeapObjectTag)); 120 __ mov(r1, Operand(r0, r1, times_4, kValueOffset - kHeapObjectTag));
121 } 121 }
122 122
123 123
124 // Helper function used to check that a value is either not a function
125 // or is loaded if it is a function.
126 static void GenerateCheckNonFunctionOrLoaded(MacroAssembler* masm, Label* miss,
127 Register value, Register scratch) {
128 Label done;
129 // Check if the value is a Smi.
130 __ test(value, Immediate(kSmiTagMask));
131 __ j(zero, &done, not_taken);
132 // Check if the value is a function.
133 __ mov(scratch, FieldOperand(value, HeapObject::kMapOffset));
134 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
135 __ cmp(scratch, JS_FUNCTION_TYPE);
136 __ j(not_equal, &done, taken);
137 // Check if the function has been loaded.
138 __ mov(scratch, FieldOperand(value, JSFunction::kSharedFunctionInfoOffset));
139 __ mov(scratch,
140 FieldOperand(scratch, SharedFunctionInfo::kLazyLoadDataOffset));
141 __ cmp(scratch, Factory::undefined_value());
142 __ j(not_equal, miss, not_taken);
143 __ bind(&done);
144 }
145
146
124 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 147 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
125 // ----------- S t a t e ------------- 148 // ----------- S t a t e -------------
126 // -- ecx : name 149 // -- ecx : name
127 // -- esp[0] : return address 150 // -- esp[0] : return address
128 // -- esp[4] : receiver 151 // -- esp[4] : receiver
129 // ----------------------------------- 152 // -----------------------------------
130 153
131 Label miss; 154 Label miss;
132 155
133 __ mov(eax, Operand(esp, kPointerSize)); 156 __ mov(eax, Operand(esp, kPointerSize));
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 __ bind(&check_string); 252 __ bind(&check_string);
230 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); 253 __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
231 __ test(ebx, Immediate(String::kIsArrayIndexMask)); 254 __ test(ebx, Immediate(String::kIsArrayIndexMask));
232 __ j(not_zero, &index_string, not_taken); 255 __ j(not_zero, &index_string, not_taken);
233 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 256 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
234 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 257 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
235 __ test(ebx, Immediate(kIsSymbolMask)); 258 __ test(ebx, Immediate(kIsSymbolMask));
236 __ j(not_zero, &slow, not_taken); 259 __ j(not_zero, &slow, not_taken);
237 // Probe the dictionary leaving result in ecx. 260 // Probe the dictionary leaving result in ecx.
238 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax); 261 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax);
262 GenerateCheckNonFunctionOrLoaded(masm, &slow, ecx, edx);
239 __ mov(eax, Operand(ecx)); 263 __ mov(eax, Operand(ecx));
240 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); 264 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
241 __ ret(0); 265 __ ret(0);
242 // Array index string: If short enough use cache in length/hash field (ebx). 266 // Array index string: If short enough use cache in length/hash field (ebx).
243 // We assert that there are enough bits in an int32_t after the hash shift 267 // We assert that there are enough bits in an int32_t after the hash shift
244 // bits have been subtracted to allow space for the length and the cached 268 // bits have been subtracted to allow space for the length and the cached
245 // array index. 269 // array index.
246 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 270 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
247 (1 << (String::kShortLengthShift - String::kHashShift))); 271 (1 << (String::kShortLengthShift - String::kHashShift)));
248 __ bind(&index_string); 272 __ bind(&index_string);
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 __ mov(edi, Operand(edx)); 473 __ mov(edi, Operand(edx));
450 __ test(edx, Immediate(kSmiTagMask)); 474 __ test(edx, Immediate(kSmiTagMask));
451 __ j(zero, miss, not_taken); 475 __ j(zero, miss, not_taken);
452 476
453 // Check that the value is a JavaScript function. 477 // Check that the value is a JavaScript function.
454 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); 478 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
455 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset)); 479 __ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset));
456 __ cmp(edx, JS_FUNCTION_TYPE); 480 __ cmp(edx, JS_FUNCTION_TYPE);
457 __ j(not_equal, miss, not_taken); 481 __ j(not_equal, miss, not_taken);
458 482
483 // Check that the function has been loaded.
484 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
485 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kLazyLoadDataOffset));
486 __ cmp(edx, Factory::undefined_value());
487 __ j(not_equal, miss, not_taken);
488
459 // Patch the receiver with the global proxy if necessary. 489 // Patch the receiver with the global proxy if necessary.
460 if (is_global_object) { 490 if (is_global_object) {
461 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 491 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
462 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 492 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
463 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 493 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
464 } 494 }
465 495
466 // Invoke the function. 496 // Invoke the function.
467 ParameterCount actual(argc); 497 ParameterCount actual(argc);
468 __ InvokeFunction(edi, actual, JUMP_FUNCTION); 498 __ InvokeFunction(edi, actual, JUMP_FUNCTION);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 // If this assert fails, we have to check upper bound too. 650 // If this assert fails, we have to check upper bound too.
621 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 651 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
622 652
623 // Check for access to global object (unlikely). 653 // Check for access to global object (unlikely).
624 __ cmp(edx, JS_GLOBAL_PROXY_TYPE); 654 __ cmp(edx, JS_GLOBAL_PROXY_TYPE);
625 __ j(equal, &global, not_taken); 655 __ j(equal, &global, not_taken);
626 656
627 // Search the dictionary placing the result in eax. 657 // Search the dictionary placing the result in eax.
628 __ bind(&probe); 658 __ bind(&probe);
629 GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx); 659 GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx);
660 GenerateCheckNonFunctionOrLoaded(masm, &miss, eax, edx);
630 __ ret(0); 661 __ ret(0);
631 662
632 // Global object access: Check access rights. 663 // Global object access: Check access rights.
633 __ bind(&global); 664 __ bind(&global);
634 __ CheckAccessGlobalProxy(eax, edx, &miss); 665 __ CheckAccessGlobalProxy(eax, edx, &miss);
635 __ jmp(&probe); 666 __ jmp(&probe);
636 667
637 // Cache miss: Restore receiver from stack and jump to runtime. 668 // Cache miss: Restore receiver from stack and jump to runtime.
638 __ bind(&miss); 669 __ bind(&miss);
639 __ mov(eax, Operand(esp, 1 * kPointerSize)); 670 __ mov(eax, Operand(esp, 1 * kPointerSize));
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 838
808 // Do tail-call to runtime routine. 839 // Do tail-call to runtime routine.
809 __ TailCallRuntime( 840 __ TailCallRuntime(
810 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); 841 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
811 } 842 }
812 843
813 #undef __ 844 #undef __
814 845
815 846
816 } } // namespace v8::internal 847 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic-arm.cc ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698