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

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

Issue 93066: Built-in JSON support (Closed)
Patch Set: Created 11 years, 8 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
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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 __ test(Operand(r0, r1, times_4, kDetailsOffset - kHeapObjectTag), 116 __ test(Operand(r0, r1, times_4, kDetailsOffset - kHeapObjectTag),
117 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); 117 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize));
118 __ j(not_zero, miss_label, not_taken); 118 __ j(not_zero, miss_label, not_taken);
119 119
120 // Get the value at the masked, scaled index. 120 // Get the value at the masked, scaled index.
121 const int kValueOffset = kElementsStartOffset + kPointerSize; 121 const int kValueOffset = kElementsStartOffset + kPointerSize;
122 __ mov(r1, Operand(r0, r1, times_4, kValueOffset - kHeapObjectTag)); 122 __ mov(r1, Operand(r0, r1, times_4, kValueOffset - kHeapObjectTag));
123 } 123 }
124 124
125 125
126 // Helper function used to check that a value is either not a function 126 // Helper function used to check that a value is either not an object
127 // or is loaded if it is a function. 127 // or is loaded if it is an object.
128 static void GenerateCheckNonFunctionOrLoaded(MacroAssembler* masm, Label* miss, 128 static void GenerateCheckNonObjectOrLoaded(MacroAssembler* masm, Label* miss,
129 Register value, Register scratch) { 129 Register value, Register scratch) {
130 Label done; 130 Label done;
131 // Check if the value is a Smi. 131 // Check if the value is a Smi.
132 __ test(value, Immediate(kSmiTagMask)); 132 __ test(value, Immediate(kSmiTagMask));
133 __ j(zero, &done, not_taken); 133 __ j(zero, &done, not_taken);
134 // Check if the value is a function. 134 // Check if the object has been loaded.
135 __ CmpObjectType(value, JS_FUNCTION_TYPE, scratch); 135 __ mov(scratch, FieldOperand(value, JSFunction::kMapOffset));
136 __ j(not_equal, &done, taken); 136 __ mov(scratch, FieldOperand(scratch, Map::kBitField2Offset));
137 // Check if the function has been loaded. 137 __ test(scratch, Immediate(1 << Map::kNeedsLoading));
138 __ mov(scratch, FieldOperand(value, JSFunction::kSharedFunctionInfoOffset)); 138 __ j(not_zero, miss, not_taken);
139 __ mov(scratch,
140 FieldOperand(scratch, SharedFunctionInfo::kLazyLoadDataOffset));
141 __ cmp(scratch, Factory::undefined_value());
142 __ j(not_equal, miss, not_taken);
143 __ bind(&done); 139 __ bind(&done);
144 } 140 }
145 141
146 142
147 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 143 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
148 // ----------- S t a t e ------------- 144 // ----------- S t a t e -------------
149 // -- ecx : name 145 // -- ecx : name
150 // -- esp[0] : return address 146 // -- esp[0] : return address
151 // -- esp[4] : receiver 147 // -- esp[4] : receiver
152 // ----------------------------------- 148 // -----------------------------------
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 __ bind(&check_string); 257 __ bind(&check_string);
262 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); 258 __ mov(ebx, FieldOperand(eax, String::kLengthOffset));
263 __ test(ebx, Immediate(String::kIsArrayIndexMask)); 259 __ test(ebx, Immediate(String::kIsArrayIndexMask));
264 __ j(not_zero, &index_string, not_taken); 260 __ j(not_zero, &index_string, not_taken);
265 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 261 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
266 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 262 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
267 __ test(ebx, Immediate(kIsSymbolMask)); 263 __ test(ebx, Immediate(kIsSymbolMask));
268 __ j(not_zero, &slow, not_taken); 264 __ j(not_zero, &slow, not_taken);
269 // Probe the dictionary leaving result in ecx. 265 // Probe the dictionary leaving result in ecx.
270 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax); 266 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax);
271 GenerateCheckNonFunctionOrLoaded(masm, &slow, ecx, edx); 267 GenerateCheckNonObjectOrLoaded(masm, &slow, ecx, edx);
272 __ mov(eax, Operand(ecx)); 268 __ mov(eax, Operand(ecx));
273 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); 269 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
274 __ ret(0); 270 __ ret(0);
275 // Array index string: If short enough use cache in length/hash field (ebx). 271 // Array index string: If short enough use cache in length/hash field (ebx).
276 // We assert that there are enough bits in an int32_t after the hash shift 272 // We assert that there are enough bits in an int32_t after the hash shift
277 // bits have been subtracted to allow space for the length and the cached 273 // bits have been subtracted to allow space for the length and the cached
278 // array index. 274 // array index.
279 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 275 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
280 (1 << (String::kShortLengthShift - String::kHashShift))); 276 (1 << (String::kShortLengthShift - String::kHashShift)));
281 __ bind(&index_string); 277 __ bind(&index_string);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 bool is_global_object, 477 bool is_global_object,
482 Label* miss) { 478 Label* miss) {
483 // Search dictionary - put result in register edx. 479 // Search dictionary - put result in register edx.
484 GenerateDictionaryLoad(masm, miss, eax, edx, ebx, ecx); 480 GenerateDictionaryLoad(masm, miss, eax, edx, ebx, ecx);
485 481
486 // Move the result to register edi and check that it isn't a smi. 482 // Move the result to register edi and check that it isn't a smi.
487 __ mov(edi, Operand(edx)); 483 __ mov(edi, Operand(edx));
488 __ test(edx, Immediate(kSmiTagMask)); 484 __ test(edx, Immediate(kSmiTagMask));
489 __ j(zero, miss, not_taken); 485 __ j(zero, miss, not_taken);
490 486
491 // Check that the value is a JavaScript function. 487 // Check that the object has been loaded.
Mads Ager (chromium) 2009/04/23 19:09:25 You are removing a JSFunction check here - you sho
492 __ CmpObjectType(edx, JS_FUNCTION_TYPE, edx); 488 __ mov(edx, FieldOperand(edi, JSFunction::kMapOffset));
493 __ j(not_equal, miss, not_taken); 489 __ mov(edx, FieldOperand(edx, Map::kBitField2Offset));
494 490 __ test(edx, Immediate(1 << Map::kNeedsLoading));
495 // Check that the function has been loaded. 491 __ j(not_zero, miss, not_taken);
496 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
497 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kLazyLoadDataOffset));
498 __ cmp(edx, Factory::undefined_value());
499 __ j(not_equal, miss, not_taken);
500 492
501 // Patch the receiver with the global proxy if necessary. 493 // Patch the receiver with the global proxy if necessary.
502 if (is_global_object) { 494 if (is_global_object) {
503 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 495 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
504 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 496 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
505 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 497 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
506 } 498 }
507 499
508 // Invoke the function. 500 // Invoke the function.
509 ParameterCount actual(argc); 501 ParameterCount actual(argc);
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 __ j(equal, &global, not_taken); 668 __ j(equal, &global, not_taken);
677 669
678 // Check for non-global object that requires access check. 670 // Check for non-global object that requires access check.
679 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset)); 671 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset));
680 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); 672 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded));
681 __ j(not_zero, &miss, not_taken); 673 __ j(not_zero, &miss, not_taken);
682 674
683 // Search the dictionary placing the result in eax. 675 // Search the dictionary placing the result in eax.
684 __ bind(&probe); 676 __ bind(&probe);
685 GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx); 677 GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx);
686 GenerateCheckNonFunctionOrLoaded(masm, &miss, eax, edx); 678 GenerateCheckNonObjectOrLoaded(masm, &miss, eax, edx);
687 __ ret(0); 679 __ ret(0);
688 680
689 // Global object access: Check access rights. 681 // Global object access: Check access rights.
690 __ bind(&global); 682 __ bind(&global);
691 __ CheckAccessGlobalProxy(eax, edx, &miss); 683 __ CheckAccessGlobalProxy(eax, edx, &miss);
692 __ jmp(&probe); 684 __ jmp(&probe);
693 685
694 // Cache miss: Restore receiver from stack and jump to runtime. 686 // Cache miss: Restore receiver from stack and jump to runtime.
695 __ bind(&miss); 687 __ bind(&miss);
696 __ mov(eax, Operand(esp, 1 * kPointerSize)); 688 __ mov(eax, Operand(esp, 1 * kPointerSize));
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 893
902 // Do tail-call to runtime routine. 894 // Do tail-call to runtime routine.
903 __ TailCallRuntime( 895 __ TailCallRuntime(
904 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); 896 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3);
905 } 897 }
906 898
907 #undef __ 899 #undef __
908 900
909 901
910 } } // namespace v8::internal 902 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698