OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 | 164 |
165 // Return the generated code. | 165 // Return the generated code. |
166 String* function_name = NULL; | 166 String* function_name = NULL; |
167 if (function->shared()->name()->IsString()) { | 167 if (function->shared()->name()->IsString()) { |
168 function_name = String::cast(function->shared()->name()); | 168 function_name = String::cast(function->shared()->name()); |
169 } | 169 } |
170 return GetCode(CONSTANT_FUNCTION, function_name); | 170 return GetCode(CONSTANT_FUNCTION, function_name); |
171 } | 171 } |
172 | 172 |
173 | 173 |
174 Object* CallStubCompiler::CompileCallField(Object* a, | 174 Object* CallStubCompiler::CompileCallField(Object* object, |
175 JSObject* b, | 175 JSObject* holder, |
176 int c, | 176 int index, |
177 String* d) { | 177 String* name) { |
178 // TODO(X64): Implement a real stub. | 178 // ----------- S t a t e ------------- |
179 return Failure::InternalError(); | 179 // ----------------------------------- |
| 180 // rsp[0] return address |
| 181 // rsp[8] argument argc |
| 182 // rsp[16] argument argc - 1 |
| 183 // ... |
| 184 // rsp[argc * 8] argument 1 |
| 185 // rsp[(argc + 1) * 8] argument 0 = receiver |
| 186 // rsp[(argc + 2) * 8] function name |
| 187 Label miss; |
| 188 |
| 189 // Get the receiver from the stack. |
| 190 const int argc = arguments().immediate(); |
| 191 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
| 192 |
| 193 // Check that the receiver isn't a smi. |
| 194 __ testl(rdx, Immediate(kSmiTagMask)); |
| 195 __ j(zero, &miss); |
| 196 |
| 197 // Do the right check and compute the holder register. |
| 198 Register reg = |
| 199 CheckPrototypes(JSObject::cast(object), rdx, holder, |
| 200 rbx, rcx, name, &miss); |
| 201 |
| 202 GenerateFastPropertyLoad(masm(), rdi, reg, holder, index); |
| 203 |
| 204 // Check that the function really is a function. |
| 205 __ testl(rdi, Immediate(kSmiTagMask)); |
| 206 __ j(zero, &miss); |
| 207 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rbx); |
| 208 __ j(not_equal, &miss); |
| 209 |
| 210 // Patch the receiver on the stack with the global proxy if |
| 211 // necessary. |
| 212 if (object->IsGlobalObject()) { |
| 213 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
| 214 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
| 215 } |
| 216 |
| 217 // Invoke the function. |
| 218 __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION); |
| 219 |
| 220 // Handle call cache miss. |
| 221 __ bind(&miss); |
| 222 Handle<Code> ic = ComputeCallMiss(arguments().immediate()); |
| 223 __ Jump(ic, RelocInfo::CODE_TARGET); |
| 224 |
| 225 // Return the generated code. |
| 226 return GetCode(FIELD, name); |
180 } | 227 } |
181 | 228 |
182 | 229 |
183 Object* CallStubCompiler::CompileCallInterceptor(Object* a, | 230 Object* CallStubCompiler::CompileCallInterceptor(Object* a, |
184 JSObject* b, | 231 JSObject* b, |
185 String* c) { | 232 String* c) { |
186 // TODO(X64): Implement a real stub. | 233 // TODO(X64): Implement a real stub. |
187 return Failure::InternalError(); | 234 return Failure::InternalError(); |
188 } | 235 } |
189 | 236 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 Factory::the_hole_value()); | 374 Factory::the_hole_value()); |
328 __ j(not_equal, miss); | 375 __ j(not_equal, miss); |
329 } | 376 } |
330 object = JSObject::cast(object->GetPrototype()); | 377 object = JSObject::cast(object->GetPrototype()); |
331 } | 378 } |
332 | 379 |
333 // Return the register containing the holder. | 380 // Return the register containing the holder. |
334 return result; | 381 return result; |
335 } | 382 } |
336 | 383 |
| 384 #undef __ |
| 385 |
| 386 //----------------------------------------------------------------------------- |
| 387 // StubCompiler static helper functions |
| 388 |
| 389 #define __ ACCESS_MASM(masm) |
337 | 390 |
338 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, | 391 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, |
339 int index, | 392 int index, |
340 Register prototype) { | 393 Register prototype) { |
341 // Load the global or builtins object from the current context. | 394 // Load the global or builtins object from the current context. |
342 masm->movq(prototype, | 395 __ movq(prototype, |
343 Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 396 Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
344 // Load the global context from the global or builtins object. | 397 // Load the global context from the global or builtins object. |
345 masm->movq(prototype, | 398 __ movq(prototype, |
346 FieldOperand(prototype, GlobalObject::kGlobalContextOffset)); | 399 FieldOperand(prototype, GlobalObject::kGlobalContextOffset)); |
347 // Load the function from the global context. | 400 // Load the function from the global context. |
348 masm->movq(prototype, Operand(prototype, Context::SlotOffset(index))); | 401 __ movq(prototype, Operand(prototype, Context::SlotOffset(index))); |
349 // Load the initial map. The global functions all have initial maps. | 402 // Load the initial map. The global functions all have initial maps. |
350 masm->movq(prototype, | 403 __ movq(prototype, |
351 FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); | 404 FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); |
352 // Load the prototype from the initial map. | 405 // Load the prototype from the initial map. |
353 masm->movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); | 406 __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); |
| 407 } |
| 408 |
| 409 |
| 410 // Load a fast property out of a holder object (src). In-object properties |
| 411 // are loaded directly otherwise the property is loaded from the properties |
| 412 // fixed array. |
| 413 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, |
| 414 Register dst, Register src, |
| 415 JSObject* holder, int index) { |
| 416 // Adjust for the number of properties stored in the holder. |
| 417 index -= holder->map()->inobject_properties(); |
| 418 if (index < 0) { |
| 419 // Get the property straight out of the holder. |
| 420 int offset = holder->map()->instance_size() + (index * kPointerSize); |
| 421 __ movq(dst, FieldOperand(src, offset)); |
| 422 } else { |
| 423 // Calculate the offset into the properties array. |
| 424 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| 425 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset)); |
| 426 __ movq(dst, FieldOperand(dst, offset)); |
| 427 } |
354 } | 428 } |
355 | 429 |
356 #undef __ | 430 #undef __ |
357 | 431 |
358 | 432 |
359 } } // namespace v8::internal | 433 } } // namespace v8::internal |
OLD | NEW |