OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 | 315 |
316 // Return the constant value. | 316 // Return the constant value. |
317 __ mov(eax, Handle<Object>(value)); | 317 __ mov(eax, Handle<Object>(value)); |
318 __ ret(0); | 318 __ ret(0); |
319 } | 319 } |
320 | 320 |
321 | 321 |
322 void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm, | 322 void StubCompiler::GenerateLoadInterceptor(MacroAssembler* masm, |
323 JSObject* object, | 323 JSObject* object, |
324 JSObject* holder, | 324 JSObject* holder, |
325 Smi* lookup_hint, | |
326 Register receiver, | 325 Register receiver, |
327 Register name, | 326 Register name, |
328 Register scratch1, | 327 Register scratch1, |
329 Register scratch2, | 328 Register scratch2, |
330 Label* miss_label) { | 329 Label* miss_label) { |
331 // Check that the receiver isn't a smi. | 330 // Check that the receiver isn't a smi. |
332 __ test(receiver, Immediate(kSmiTagMask)); | 331 __ test(receiver, Immediate(kSmiTagMask)); |
333 __ j(zero, miss_label, not_taken); | 332 __ j(zero, miss_label, not_taken); |
334 | 333 |
335 // Check that the maps haven't changed. | 334 // Check that the maps haven't changed. |
336 Register reg = | 335 Register reg = |
337 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); | 336 masm->CheckMaps(object, receiver, holder, scratch1, scratch2, miss_label); |
338 | 337 |
339 // Push the arguments on the JS stack of the caller. | 338 // Push the arguments on the JS stack of the caller. |
340 __ pop(scratch2); // remove return address | 339 __ pop(scratch2); // remove return address |
341 __ push(receiver); // receiver | 340 __ push(receiver); // receiver |
342 __ push(reg); // holder | 341 __ push(reg); // holder |
343 __ push(name); // name | 342 __ push(name); // name |
344 // TODO(367): Maybe don't push lookup_hint for LOOKUP_IN_HOLDER and/or | |
345 // LOOKUP_IN_PROTOTYPE, but use a special version of lookup method? | |
346 __ push(Immediate(lookup_hint)); | |
347 __ push(scratch2); // restore return address | 343 __ push(scratch2); // restore return address |
348 | 344 |
349 // Do tail-call to the runtime system. | 345 // Do tail-call to the runtime system. |
350 ExternalReference load_ic_property = | 346 ExternalReference load_ic_property = |
351 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); | 347 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); |
352 __ TailCallRuntime(load_ic_property, 4); | 348 __ TailCallRuntime(load_ic_property, 3); |
353 } | 349 } |
354 | 350 |
355 | 351 |
356 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { | 352 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { |
357 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); | 353 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); |
358 Code* code = NULL; | 354 Code* code = NULL; |
359 if (kind == Code::LOAD_IC) { | 355 if (kind == Code::LOAD_IC) { |
360 code = Builtins::builtin(Builtins::LoadIC_Miss); | 356 code = Builtins::builtin(Builtins::LoadIC_Miss); |
361 } else { | 357 } else { |
362 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); | 358 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 Register reg = | 663 Register reg = |
668 masm()->CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss); | 664 masm()->CheckMaps(JSObject::cast(object), edx, holder, ebx, ecx, &miss); |
669 | 665 |
670 // Enter an internal frame. | 666 // Enter an internal frame. |
671 __ EnterInternalFrame(); | 667 __ EnterInternalFrame(); |
672 | 668 |
673 // Push arguments on the expression stack. | 669 // Push arguments on the expression stack. |
674 __ push(edx); // receiver | 670 __ push(edx); // receiver |
675 __ push(reg); // holder | 671 __ push(reg); // holder |
676 __ push(Operand(ebp, (argc + 3) * kPointerSize)); // name | 672 __ push(Operand(ebp, (argc + 3) * kPointerSize)); // name |
677 __ push(Immediate(holder->InterceptorPropertyLookupHint(name))); | |
678 | 673 |
679 // Perform call. | 674 // Perform call. |
680 ExternalReference load_interceptor = | 675 ExternalReference load_interceptor = |
681 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); | 676 ExternalReference(IC_Utility(IC::kLoadInterceptorProperty)); |
682 __ mov(eax, Immediate(4)); | 677 __ mov(eax, Immediate(3)); |
683 __ mov(ebx, Immediate(load_interceptor)); | 678 __ mov(ebx, Immediate(load_interceptor)); |
684 | 679 |
685 CEntryStub stub; | 680 CEntryStub stub; |
686 __ CallStub(&stub); | 681 __ CallStub(&stub); |
687 | 682 |
688 // Move result to edi and restore receiver. | 683 // Move result to edi and restore receiver. |
689 __ mov(edi, eax); | 684 __ mov(edi, eax); |
690 __ mov(edx, Operand(ebp, (argc + 2) * kPointerSize)); // receiver | 685 __ mov(edx, Operand(ebp, (argc + 2) * kPointerSize)); // receiver |
691 | 686 |
692 // Exit frame. | 687 // Exit frame. |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 JSObject* holder, | 967 JSObject* holder, |
973 String* name) { | 968 String* name) { |
974 // ----------- S t a t e ------------- | 969 // ----------- S t a t e ------------- |
975 // -- ecx : name | 970 // -- ecx : name |
976 // -- esp[0] : return address | 971 // -- esp[0] : return address |
977 // -- esp[4] : receiver | 972 // -- esp[4] : receiver |
978 // ----------------------------------- | 973 // ----------------------------------- |
979 Label miss; | 974 Label miss; |
980 | 975 |
981 __ mov(eax, (Operand(esp, kPointerSize))); | 976 __ mov(eax, (Operand(esp, kPointerSize))); |
982 // TODO(368): Compile in the whole chain: all the interceptors in | 977 GenerateLoadInterceptor(masm(), receiver, holder, eax, ecx, edx, ebx, &miss); |
983 // prototypes and ultimate answer. | |
984 GenerateLoadInterceptor(masm(), | |
985 receiver, | |
986 holder, | |
987 holder->InterceptorPropertyLookupHint(name), | |
988 eax, | |
989 ecx, | |
990 edx, | |
991 ebx, | |
992 &miss); | |
993 | |
994 __ bind(&miss); | 978 __ bind(&miss); |
995 GenerateLoadMiss(masm(), Code::LOAD_IC); | 979 GenerateLoadMiss(masm(), Code::LOAD_IC); |
996 | 980 |
997 // Return the generated code. | 981 // Return the generated code. |
998 return GetCode(INTERCEPTOR, name); | 982 return GetCode(INTERCEPTOR, name); |
999 } | 983 } |
1000 | 984 |
1001 | 985 |
1002 Object* KeyedLoadStubCompiler::CompileLoadField(String* name, | 986 Object* KeyedLoadStubCompiler::CompileLoadField(String* name, |
1003 JSObject* receiver, | 987 JSObject* receiver, |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 Label miss; | 1082 Label miss; |
1099 | 1083 |
1100 __ mov(eax, (Operand(esp, kPointerSize))); | 1084 __ mov(eax, (Operand(esp, kPointerSize))); |
1101 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); | 1085 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); |
1102 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); | 1086 __ IncrementCounter(&Counters::keyed_load_interceptor, 1); |
1103 | 1087 |
1104 // Check that the name has not changed. | 1088 // Check that the name has not changed. |
1105 __ cmp(Operand(eax), Immediate(Handle<String>(name))); | 1089 __ cmp(Operand(eax), Immediate(Handle<String>(name))); |
1106 __ j(not_equal, &miss, not_taken); | 1090 __ j(not_equal, &miss, not_taken); |
1107 | 1091 |
1108 GenerateLoadInterceptor(masm(), | 1092 GenerateLoadInterceptor(masm(), receiver, holder, ecx, eax, edx, ebx, &miss); |
1109 receiver, | |
1110 holder, | |
1111 Smi::FromInt(JSObject::kLookupInHolder), | |
1112 ecx, | |
1113 eax, | |
1114 edx, | |
1115 ebx, | |
1116 &miss); | |
1117 __ bind(&miss); | 1093 __ bind(&miss); |
1118 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); | 1094 __ DecrementCounter(&Counters::keyed_load_interceptor, 1); |
1119 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1095 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1120 | 1096 |
1121 // Return the generated code. | 1097 // Return the generated code. |
1122 return GetCode(INTERCEPTOR, name); | 1098 return GetCode(INTERCEPTOR, name); |
1123 } | 1099 } |
1124 | 1100 |
1125 | 1101 |
1126 | 1102 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1175 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1200 | 1176 |
1201 // Return the generated code. | 1177 // Return the generated code. |
1202 return GetCode(CALLBACKS, name); | 1178 return GetCode(CALLBACKS, name); |
1203 } | 1179 } |
1204 | 1180 |
1205 | 1181 |
1206 #undef __ | 1182 #undef __ |
1207 | 1183 |
1208 } } // namespace v8::internal | 1184 } } // namespace v8::internal |
OLD | NEW |