| OLD | NEW |
| 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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 152 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 153 __ cmp(scratch, JS_ARRAY_TYPE); | 153 __ cmp(scratch, JS_ARRAY_TYPE); |
| 154 __ j(not_equal, miss_label, not_taken); | 154 __ j(not_equal, miss_label, not_taken); |
| 155 | 155 |
| 156 // Load length directly from the JS array. | 156 // Load length directly from the JS array. |
| 157 __ mov(eax, FieldOperand(receiver, JSArray::kLengthOffset)); | 157 __ mov(eax, FieldOperand(receiver, JSArray::kLengthOffset)); |
| 158 __ ret(0); | 158 __ ret(0); |
| 159 } | 159 } |
| 160 | 160 |
| 161 | 161 |
| 162 void StubCompiler::GenerateLoadShortStringLength(MacroAssembler* masm, | 162 // Generate code to check if an object is a string. If the object is |
| 163 Register receiver, | 163 // a string, the map's instance type is left in the scratch register. |
| 164 Register scratch, | 164 static void GenerateStringCheck(MacroAssembler* masm, |
| 165 Label* miss_label) { | 165 Register receiver, |
| 166 // Check that the receiver isn't a smi. | 166 Register scratch, |
| 167 Label* smi, |
| 168 Label* non_string_object) { |
| 169 // Check that the object isn't a smi. |
| 167 __ test(receiver, Immediate(kSmiTagMask)); | 170 __ test(receiver, Immediate(kSmiTagMask)); |
| 168 __ j(zero, miss_label, not_taken); | 171 __ j(zero, smi, not_taken); |
| 169 | 172 |
| 170 // Check that the object is a short string. | 173 // Check that the object is a string. |
| 171 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 174 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 172 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 175 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); |
| 173 __ and_(scratch, kIsNotStringMask | kStringSizeMask); | 176 ASSERT(kNotStringTag != 0); |
| 174 __ cmp(scratch, kStringTag | kShortStringTag); | 177 __ test(scratch, Immediate(kNotStringTag)); |
| 175 __ j(not_equal, miss_label, not_taken); | 178 __ j(not_zero, non_string_object, not_taken); |
| 176 | |
| 177 // Load length directly from the string. | |
| 178 __ mov(eax, FieldOperand(receiver, String::kLengthOffset)); | |
| 179 __ shr(eax, String::kShortLengthShift); | |
| 180 __ shl(eax, kSmiTagSize); | |
| 181 __ ret(0); | |
| 182 } | |
| 183 | |
| 184 void StubCompiler::GenerateLoadMediumStringLength(MacroAssembler* masm, | |
| 185 Register receiver, | |
| 186 Register scratch, | |
| 187 Label* miss_label) { | |
| 188 // Check that the receiver isn't a smi. | |
| 189 __ test(receiver, Immediate(kSmiTagMask)); | |
| 190 __ j(zero, miss_label, not_taken); | |
| 191 | |
| 192 // Check that the object is a short string. | |
| 193 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | |
| 194 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | |
| 195 __ and_(scratch, kIsNotStringMask | kStringSizeMask); | |
| 196 __ cmp(scratch, kStringTag | kMediumStringTag); | |
| 197 __ j(not_equal, miss_label, not_taken); | |
| 198 | |
| 199 // Load length directly from the string. | |
| 200 __ mov(eax, FieldOperand(receiver, String::kLengthOffset)); | |
| 201 __ shr(eax, String::kMediumLengthShift); | |
| 202 __ shl(eax, kSmiTagSize); | |
| 203 __ ret(0); | |
| 204 } | 179 } |
| 205 | 180 |
| 206 | 181 |
| 207 void StubCompiler::GenerateLoadLongStringLength(MacroAssembler* masm, | 182 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, |
| 208 Register receiver, | 183 Register receiver, |
| 209 Register scratch, | 184 Register scratch, |
| 210 Label* miss_label) { | 185 Label* miss) { |
| 211 // Check that the receiver isn't a smi. | 186 Label load_length, check_wrapper; |
| 212 __ test(receiver, Immediate(kSmiTagMask)); | |
| 213 __ j(zero, miss_label, not_taken); | |
| 214 | 187 |
| 215 // Check that the object is a short string. | 188 // Check if the object is a string leaving the instance type in the |
| 216 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 189 // scratch register. |
| 217 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); | 190 GenerateStringCheck(masm, receiver, scratch, miss, &check_wrapper); |
| 218 __ and_(scratch, kIsNotStringMask | kStringSizeMask); | |
| 219 __ cmp(scratch, kStringTag | kLongStringTag); | |
| 220 __ j(not_equal, miss_label, not_taken); | |
| 221 | 191 |
| 222 // Load length directly from the string. | 192 // Load length directly from the string. |
| 193 __ bind(&load_length); |
| 194 __ and_(scratch, kStringSizeMask); |
| 223 __ mov(eax, FieldOperand(receiver, String::kLengthOffset)); | 195 __ mov(eax, FieldOperand(receiver, String::kLengthOffset)); |
| 224 __ shr(eax, String::kLongLengthShift); | 196 // ecx is also the receiver. |
| 197 __ lea(ecx, Operand(scratch, String::kLongLengthShift)); |
| 198 __ shr(eax); // ecx is implicit shift register. |
| 225 __ shl(eax, kSmiTagSize); | 199 __ shl(eax, kSmiTagSize); |
| 226 __ ret(0); | 200 __ ret(0); |
| 201 |
| 202 // Check if the object is a JSValue wrapper. |
| 203 __ bind(&check_wrapper); |
| 204 __ cmp(scratch, JS_VALUE_TYPE); |
| 205 __ j(not_equal, miss, not_taken); |
| 206 |
| 207 // Check if the wrapped value is a string and load the length |
| 208 // directly if it is. |
| 209 __ mov(receiver, FieldOperand(receiver, JSValue::kValueOffset)); |
| 210 GenerateStringCheck(masm, receiver, scratch, miss, miss); |
| 211 __ jmp(&load_length); |
| 227 } | 212 } |
| 228 | 213 |
| 229 | 214 |
| 230 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, | 215 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, |
| 231 Register receiver, | 216 Register receiver, |
| 232 Register scratch1, | 217 Register scratch1, |
| 233 Register scratch2, | 218 Register scratch2, |
| 234 Label* miss_label) { | 219 Label* miss_label) { |
| 235 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); | 220 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); |
| 236 __ mov(eax, Operand(scratch1)); | 221 __ mov(eax, Operand(scratch1)); |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 GenerateFastPropertyLoad(masm(), edi, reg, holder, index); | 498 GenerateFastPropertyLoad(masm(), edi, reg, holder, index); |
| 514 | 499 |
| 515 // Check that the function really is a function. | 500 // Check that the function really is a function. |
| 516 __ test(edi, Immediate(kSmiTagMask)); | 501 __ test(edi, Immediate(kSmiTagMask)); |
| 517 __ j(zero, &miss, not_taken); | 502 __ j(zero, &miss, not_taken); |
| 518 __ mov(ebx, FieldOperand(edi, HeapObject::kMapOffset)); // get the map | 503 __ mov(ebx, FieldOperand(edi, HeapObject::kMapOffset)); // get the map |
| 519 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 504 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 520 __ cmp(ebx, JS_FUNCTION_TYPE); | 505 __ cmp(ebx, JS_FUNCTION_TYPE); |
| 521 __ j(not_equal, &miss, not_taken); | 506 __ j(not_equal, &miss, not_taken); |
| 522 | 507 |
| 508 // Patch the receiver on the stack with the global proxy if |
| 509 // necessary. |
| 523 if (object->IsGlobalObject()) { | 510 if (object->IsGlobalObject()) { |
| 524 // TODO(120): Patch receiver with the global proxy. | 511 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 512 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 525 } | 513 } |
| 526 | 514 |
| 527 // Invoke the function. | 515 // Invoke the function. |
| 528 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); | 516 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); |
| 529 | 517 |
| 530 // Handle call cache miss. | 518 // Handle call cache miss. |
| 531 __ bind(&miss); | 519 __ bind(&miss); |
| 532 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 520 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
| 533 __ jmp(ic, RelocInfo::CODE_TARGET); | 521 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 534 | 522 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 550 // Get the receiver from the stack. | 538 // Get the receiver from the stack. |
| 551 const int argc = arguments().immediate(); | 539 const int argc = arguments().immediate(); |
| 552 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 540 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 553 | 541 |
| 554 // Check that the receiver isn't a smi. | 542 // Check that the receiver isn't a smi. |
| 555 if (check != NUMBER_CHECK) { | 543 if (check != NUMBER_CHECK) { |
| 556 __ test(edx, Immediate(kSmiTagMask)); | 544 __ test(edx, Immediate(kSmiTagMask)); |
| 557 __ j(zero, &miss, not_taken); | 545 __ j(zero, &miss, not_taken); |
| 558 } | 546 } |
| 559 | 547 |
| 548 // Make sure that it's okay not to patch the on stack receiver |
| 549 // unless we're doing a receiver map check. |
| 550 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); |
| 551 |
| 560 switch (check) { | 552 switch (check) { |
| 561 case RECEIVER_MAP_CHECK: | 553 case RECEIVER_MAP_CHECK: |
| 562 // Check that the maps haven't changed. | 554 // Check that the maps haven't changed. |
| 563 __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss); | 555 __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss); |
| 556 |
| 557 // Patch the receiver on the stack with the global proxy if |
| 558 // necessary. |
| 559 if (object->IsGlobalObject()) { |
| 560 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 561 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 562 } |
| 564 break; | 563 break; |
| 565 | 564 |
| 566 case STRING_CHECK: | 565 case STRING_CHECK: |
| 567 // Check that the object is a two-byte string or a symbol. | 566 // Check that the object is a two-byte string or a symbol. |
| 568 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 567 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 569 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 568 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| 570 __ cmp(ecx, FIRST_NONSTRING_TYPE); | 569 __ cmp(ecx, FIRST_NONSTRING_TYPE); |
| 571 __ j(above_equal, &miss, not_taken); | 570 __ j(above_equal, &miss, not_taken); |
| 572 // Check that the maps starting from the prototype haven't changed. | 571 // Check that the maps starting from the prototype haven't changed. |
| 573 GenerateLoadGlobalFunctionPrototype(masm(), | 572 GenerateLoadGlobalFunctionPrototype(masm(), |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 break; | 624 break; |
| 626 | 625 |
| 627 default: | 626 default: |
| 628 UNREACHABLE(); | 627 UNREACHABLE(); |
| 629 } | 628 } |
| 630 | 629 |
| 631 // Get the function and setup the context. | 630 // Get the function and setup the context. |
| 632 __ mov(Operand(edi), Immediate(Handle<JSFunction>(function))); | 631 __ mov(Operand(edi), Immediate(Handle<JSFunction>(function))); |
| 633 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 632 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 634 | 633 |
| 635 if (object->IsGlobalObject()) { | |
| 636 // TODO(120): Patch receiver with the global proxy. | |
| 637 } | |
| 638 | |
| 639 // Jump to the cached code (tail call). | 634 // Jump to the cached code (tail call). |
| 640 Handle<Code> code(function->code()); | 635 Handle<Code> code(function->code()); |
| 641 ParameterCount expected(function->shared()->formal_parameter_count()); | 636 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 642 __ InvokeCode(code, expected, arguments(), | 637 __ InvokeCode(code, expected, arguments(), |
| 643 RelocInfo::CODE_TARGET, JUMP_FUNCTION); | 638 RelocInfo::CODE_TARGET, JUMP_FUNCTION); |
| 644 | 639 |
| 645 // Handle call cache miss. | 640 // Handle call cache miss. |
| 646 __ bind(&miss); | 641 __ bind(&miss); |
| 647 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); | 642 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
| 648 __ jmp(ic, RelocInfo::CODE_TARGET); | 643 __ jmp(ic, RelocInfo::CODE_TARGET); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 659 // ----------------------------------- | 654 // ----------------------------------- |
| 660 | 655 |
| 661 HandleScope scope; | 656 HandleScope scope; |
| 662 Label miss; | 657 Label miss; |
| 663 | 658 |
| 664 // Get the number of arguments. | 659 // Get the number of arguments. |
| 665 const int argc = arguments().immediate(); | 660 const int argc = arguments().immediate(); |
| 666 | 661 |
| 667 // Get the receiver from the stack. | 662 // Get the receiver from the stack. |
| 668 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 663 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 664 |
| 669 // Check that the receiver isn't a smi. | 665 // Check that the receiver isn't a smi. |
| 670 __ test(edx, Immediate(kSmiTagMask)); | 666 __ test(edx, Immediate(kSmiTagMask)); |
| 671 __ j(zero, &miss, not_taken); | 667 __ j(zero, &miss, not_taken); |
| 672 | 668 |
| 673 // Check that maps have not changed and compute the holder register. | 669 // Check that maps have not changed and compute the holder register. |
| 674 Register reg = | 670 Register reg = |
| 675 __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss); | 671 __ CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss); |
| 676 | 672 |
| 677 // Enter an internal frame. | 673 // Enter an internal frame. |
| 678 __ EnterInternalFrame(); | 674 __ EnterInternalFrame(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 699 __ LeaveInternalFrame(); | 695 __ LeaveInternalFrame(); |
| 700 | 696 |
| 701 // Check that the function really is a function. | 697 // Check that the function really is a function. |
| 702 __ test(edi, Immediate(kSmiTagMask)); | 698 __ test(edi, Immediate(kSmiTagMask)); |
| 703 __ j(zero, &miss, not_taken); | 699 __ j(zero, &miss, not_taken); |
| 704 __ mov(ebx, FieldOperand(edi, HeapObject::kMapOffset)); | 700 __ mov(ebx, FieldOperand(edi, HeapObject::kMapOffset)); |
| 705 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 701 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 706 __ cmp(ebx, JS_FUNCTION_TYPE); | 702 __ cmp(ebx, JS_FUNCTION_TYPE); |
| 707 __ j(not_equal, &miss, not_taken); | 703 __ j(not_equal, &miss, not_taken); |
| 708 | 704 |
| 705 // Patch the receiver on the stack with the global proxy if |
| 706 // necessary. |
| 709 if (object->IsGlobalObject()) { | 707 if (object->IsGlobalObject()) { |
| 710 // TODO(120): Patch receiver with the global proxy. | 708 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 709 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 711 } | 710 } |
| 712 | 711 |
| 713 // Invoke the function. | 712 // Invoke the function. |
| 714 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); | 713 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION); |
| 715 | 714 |
| 716 // Handle load cache miss. | 715 // Handle load cache miss. |
| 717 __ bind(&miss); | 716 __ bind(&miss); |
| 718 Handle<Code> ic = ComputeCallMiss(argc); | 717 Handle<Code> ic = ComputeCallMiss(argc); |
| 719 __ jmp(ic, RelocInfo::CODE_TARGET); | 718 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 720 | 719 |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1146 GenerateLoadArrayLength(masm(), ecx, edx, &miss); | 1145 GenerateLoadArrayLength(masm(), ecx, edx, &miss); |
| 1147 __ bind(&miss); | 1146 __ bind(&miss); |
| 1148 __ DecrementCounter(&Counters::keyed_load_array_length, 1); | 1147 __ DecrementCounter(&Counters::keyed_load_array_length, 1); |
| 1149 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1148 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1150 | 1149 |
| 1151 // Return the generated code. | 1150 // Return the generated code. |
| 1152 return GetCode(CALLBACKS); | 1151 return GetCode(CALLBACKS); |
| 1153 } | 1152 } |
| 1154 | 1153 |
| 1155 | 1154 |
| 1156 Object* KeyedLoadStubCompiler::CompileLoadShortStringLength(String* name) { | 1155 Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { |
| 1157 // ----------- S t a t e ------------- | 1156 // ----------- S t a t e ------------- |
| 1158 // -- esp[0] : return address | 1157 // -- esp[0] : return address |
| 1159 // -- esp[4] : name | 1158 // -- esp[4] : name |
| 1160 // -- esp[8] : receiver | 1159 // -- esp[8] : receiver |
| 1161 // ----------------------------------- | 1160 // ----------------------------------- |
| 1162 HandleScope scope; | 1161 HandleScope scope; |
| 1163 Label miss; | 1162 Label miss; |
| 1164 | 1163 |
| 1165 __ mov(eax, (Operand(esp, kPointerSize))); | 1164 __ mov(eax, (Operand(esp, kPointerSize))); |
| 1166 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); | 1165 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); |
| 1167 __ IncrementCounter(&Counters::keyed_load_string_length, 1); | 1166 __ IncrementCounter(&Counters::keyed_load_string_length, 1); |
| 1168 | 1167 |
| 1169 // Check that the name has not changed. | 1168 // Check that the name has not changed. |
| 1170 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1169 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
| 1171 __ j(not_equal, &miss, not_taken); | 1170 __ j(not_equal, &miss, not_taken); |
| 1172 | 1171 |
| 1173 GenerateLoadShortStringLength(masm(), ecx, edx, &miss); | 1172 GenerateLoadStringLength(masm(), ecx, edx, &miss); |
| 1174 __ bind(&miss); | 1173 __ bind(&miss); |
| 1175 __ DecrementCounter(&Counters::keyed_load_string_length, 1); | 1174 __ DecrementCounter(&Counters::keyed_load_string_length, 1); |
| 1176 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1175 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1177 | 1176 |
| 1178 // Return the generated code. | 1177 // Return the generated code. |
| 1179 return GetCode(CALLBACKS); | 1178 return GetCode(CALLBACKS); |
| 1180 } | 1179 } |
| 1181 | 1180 |
| 1182 | 1181 |
| 1183 Object* KeyedLoadStubCompiler::CompileLoadMediumStringLength(String* name) { | |
| 1184 // ----------- S t a t e ------------- | |
| 1185 // -- esp[0] : return address | |
| 1186 // -- esp[4] : name | |
| 1187 // -- esp[8] : receiver | |
| 1188 // ----------------------------------- | |
| 1189 HandleScope scope; | |
| 1190 Label miss; | |
| 1191 | |
| 1192 __ mov(eax, (Operand(esp, kPointerSize))); | |
| 1193 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); | |
| 1194 __ IncrementCounter(&Counters::keyed_load_string_length, 1); | |
| 1195 | |
| 1196 // Check that the name has not changed. | |
| 1197 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | |
| 1198 __ j(not_equal, &miss, not_taken); | |
| 1199 | |
| 1200 GenerateLoadMediumStringLength(masm(), ecx, edx, &miss); | |
| 1201 __ bind(&miss); | |
| 1202 __ DecrementCounter(&Counters::keyed_load_string_length, 1); | |
| 1203 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | |
| 1204 | |
| 1205 // Return the generated code. | |
| 1206 return GetCode(CALLBACKS); | |
| 1207 } | |
| 1208 | |
| 1209 | |
| 1210 Object* KeyedLoadStubCompiler::CompileLoadLongStringLength(String* name) { | |
| 1211 // ----------- S t a t e ------------- | |
| 1212 // -- esp[0] : return address | |
| 1213 // -- esp[4] : name | |
| 1214 // -- esp[8] : receiver | |
| 1215 // ----------------------------------- | |
| 1216 HandleScope scope; | |
| 1217 Label miss; | |
| 1218 | |
| 1219 __ mov(eax, (Operand(esp, kPointerSize))); | |
| 1220 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); | |
| 1221 __ IncrementCounter(&Counters::keyed_load_string_length, 1); | |
| 1222 | |
| 1223 // Check that the name has not changed. | |
| 1224 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | |
| 1225 __ j(not_equal, &miss, not_taken); | |
| 1226 | |
| 1227 GenerateLoadLongStringLength(masm(), ecx, edx, &miss); | |
| 1228 __ bind(&miss); | |
| 1229 __ DecrementCounter(&Counters::keyed_load_string_length, 1); | |
| 1230 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | |
| 1231 | |
| 1232 // Return the generated code. | |
| 1233 return GetCode(CALLBACKS); | |
| 1234 } | |
| 1235 | |
| 1236 | |
| 1237 Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { | 1182 Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { |
| 1238 // ----------- S t a t e ------------- | 1183 // ----------- S t a t e ------------- |
| 1239 // -- esp[0] : return address | 1184 // -- esp[0] : return address |
| 1240 // -- esp[4] : name | 1185 // -- esp[4] : name |
| 1241 // -- esp[8] : receiver | 1186 // -- esp[8] : receiver |
| 1242 // ----------------------------------- | 1187 // ----------------------------------- |
| 1243 HandleScope scope; | 1188 HandleScope scope; |
| 1244 Label miss; | 1189 Label miss; |
| 1245 | 1190 |
| 1246 __ mov(eax, (Operand(esp, kPointerSize))); | 1191 __ mov(eax, (Operand(esp, kPointerSize))); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1257 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1202 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
| 1258 | 1203 |
| 1259 // Return the generated code. | 1204 // Return the generated code. |
| 1260 return GetCode(CALLBACKS); | 1205 return GetCode(CALLBACKS); |
| 1261 } | 1206 } |
| 1262 | 1207 |
| 1263 | 1208 |
| 1264 #undef __ | 1209 #undef __ |
| 1265 | 1210 |
| 1266 } } // namespace v8::internal | 1211 } } // namespace v8::internal |
| OLD | NEW |